为正在执行SKAction的SKSpriteNode运行新序列需如何处理?
关于SKSpriteNode运行SKAction的相关问题解答
1. 是否需要先停止节点上之前正在运行的动作?
- 默认情况下SKSpriteNode支持同时运行多个SKAction,多个动作的效果会并行叠加。如果你不停止之前的动作,新旧动作的属性修改(比如位移、缩放、透明度变化等)会同时生效,大概率会出现不符合预期的显示效果,因此需要先对之前运行的动作做处理。
- 注意不要直接在触发新动作前调用
removeAllActions(),该方法会立即终止所有正在执行的动作,导致节点状态突然跳变,没有过渡效果。
2. 实现动作平滑结束、关闭重复执行的方案
核心思路是给动作设置唯一标识,单独控制重复动作的调度,避免全局强制移除所有动作:
步骤1:给重复动作添加唯一Key
修改原有添加动作的代码,给重复执行的动作设置自定义Key,方便后续单独操作该动作:
theGem!.run(premAction, completion: { [weak theGem] in guard let theGem = theGem else { return } // 给重复动作设置唯一标识 theGem.run(repeatAction, withKey: "gemRepeatAction") })
步骤2:单独移除重复动作的调度
调用removeAction(forKey:)只会停止后续的重复动作调度,当前正在执行的这一轮动作会完整跑完,不会被打断,实现平滑结束的效果:
// 仅停止重复动作的后续循环,当前执行的动作不受影响 theGem.removeAction(forKey: "gemRepeatAction")
步骤3:调整新动作的执行逻辑
如果需要等当前正在运行的旧动作完全结束后再执行新的endsequence,可以用等待动作做包装:
// 等待时长设置为当前正在执行的单轮动作的总时长即可 let waitAction = SKAction.wait(forDuration: repeatAction.duration) let fullEndSequence = SKAction.sequence([waitAction, endsequence]) theGem.run(fullEndSequence, completion: { [weak theGem] in guard let theGem = theGem else { return } theGem.removeAllActions() theGem.run(stopAction) })
内容的提问来源于stack exchange,提问作者LuisC329
相关产品推荐
相关产品推荐

