如何确保Cocos Creator中卡牌移动runAction动画执行完毕再触发?
解决Cocos Creator 1.9中动画叠加异常的问题
嘿,这个问题我之前做卡牌交互的时候也碰到过!快速操作导致前一个动画还没跑完就触发新的,结果手牌位置乱跳,确实挺闹心的。咱们可以从这几个实用方向来解决:
方法1:直接停止现有动画再执行新的
如果你的需求是快速操作时用新动画覆盖旧的,那最简单的方式就是每次触发动画前,先停止节点上正在运行的相关动画,避免叠加。
修改你的onMoveCard方法如下:
onMoveCard(): void { // 先停止当前节点的所有动画(如果只想停移动类,可以加tag精准控制) this.node.stopAllActions(); const moveRight: cc.ActionInterval = cc.moveBy(0.1, cc.p(DragCard.currentHandSpacing, 0)); const moveLeft: cc.ActionInterval = cc.moveBy(0.1, cc.p(-DragCard.currentHandSpacing, 0)); // 根据你的逻辑选择执行左移或右移 if (/* 这里写你的右移判断条件 */) { this.node.runAction(moveRight); } else { this.node.runAction(moveLeft); } }
如果不想停止所有动画,只想针对移动动画,可以给动画设置标签:
// 给动画加tag moveRight.setTag(101); moveLeft.setTag(101); // 停止时只停对应tag的动画 this.node.stopActionByTag(101);
方法2:用状态锁保证动画顺序执行
如果你的需求是必须等前一个动画完成再执行下一个,那可以给脚本加一个状态变量,作为动画执行的“开关”:
// 类内定义一个状态变量,标记是否正在执行动画 private isAnimating: boolean = false; onMoveCard(): void { // 如果当前正在动画,直接返回,不触发新动画 if (this.isAnimating) return; this.isAnimating = true; let targetAction: cc.ActionInterval; // 选择要执行的动画 if (/* 右移条件 */) { targetAction = cc.moveBy(0.1, cc.p(DragCard.currentHandSpacing, 0)); } else { targetAction = cc.moveBy(0.1, cc.p(-DragCard.currentHandSpacing, 0)); } // 用sequence将动画和回调绑定,动画结束后解锁状态 const actionSequence = cc.sequence( targetAction, cc.callFunc(() => { this.isAnimating = false; }) ); this.node.runAction(actionSequence); }
这种方式会把用户快速触发的动画请求排队,等上一个完全执行完再跑下一个,适合需要严格保证动画顺序的场景。
总结
- 如果追求操作的即时反馈(快速切换时直接显示最新状态),选方法1;
- 如果需要动画完整执行,避免跳过中间过程,选方法2。
内容的提问来源于stack exchange,提问作者Habib Zaid




