You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何确保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

火山引擎 最新活动