← ClaudeAtlas

cocos2dx-lualisted

写 Cocos2d-x Lua 时使用。节点、触摸、动作、调度器、ccui、内存的实战规范。
Wade-DevCode/awesome-coding-skills-cn · ★ 3 · AI & Automation · score 78
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# Cocos2d-x Lua 最佳实践 ## 何时用 - 编写任何 Cocos2d-x Lua 场景、Layer、UI 组件脚本前。 - 发现内存持续增长、退出场景后内存未释放时。 - 触摸事件穿透、多层点击响应混乱,或事件监听器未被清理时。 - 动作(Action)执行异常、Scene 切换后动画仍在报错时。 - 调度器回调在节点销毁后仍被调用,导致访问空节点崩溃时。 ## 核心规则 ### 1. 节点生命周期:addChild/removeChild 必须配对,退出前清理一切 **规则:** 每个 `addChild` 都要有对应的清理路径(`removeChild` 或场景切换自动销毁);`onEnter`/`onExit` 是注册/注销外部资源(调度器、事件)的标准时机,不要在构造函数或任意时机注册后忘记注销。 **为什么:** Cocos2d-x 的 C++ 底层使用引用计数(retain/release),Lua 侧持有的 userdata 会阻止对象释放。AI 生成代码时最常犯的错误:在一个 Layer 里 `addChild` 了子节点,场景切换时只 `removeFromParent` 了 Layer,但子节点上挂的调度器回调和事件监听器没有清理,C++ 对象引用计数不归零,内存持续增长。新手则常在 `init` 里注册调度器,在 `onExit` 里忘记反注册,下次进场景又注册一次,定时器越堆越多。 **怎么做:** - 在 `onEnter` 里注册调度器和事件监听器,在 `onExit` 里注销。 - 场景/Layer 退出时调用 `node:unscheduleAllCallbacks()` 和 `eventDispatcher:removeEventListenersForTarget(node)`。 - 临时创建的节点用完即 `removeFromParent(true)`(true = cleanup,会停止其上的 Action 和调度器)。 - 养成习惯:每加一个子节点,立刻想好"它什么时候被移除"。 --- ### 2. 触摸事件:EventListener 正确注册与移除,处理吞噬与层级冲突 **规则:** 触摸事件必须用 `cc.EventListenerTouchOneByOne` 或 `cc.EventListenerTouchAllAtOnce` 注册到 `eventDispatcher`,不用旧的 `setTouchEnabled`;`setSwallowTouches(true)` 只在确实需要阻止穿透时设置,并理��其对下层 Listener 的影响;节点移除前必须 `removeEventListenersForTarget`。 **为什么:** Cocos2d-x Lua 里触摸 bug 几乎全部源于两个问题:(1)新手混用新旧 API——`layer:setTouchEnabled(true)` 在 3.x 里已废弃,和 EventDispatcher 的优先级体系完全独立,导致点击没响应却不报错,排查极为困难;(2)AI 生成的 Listener 注册了但没有对应的注销,节点 removeChild 后 C++ 对象已析构,触摸事件仍然回调进来,访问已释放的 Lua userdata 直接崩溃。`setSwallowTouches` 设错方向时,弹窗后面的按钮照样可以被点击,产生逻辑混乱。 **怎么做:** - 统一用 `cc.EventListenerTouc