SpriteKit回合制游戏:动态追加依赖前序动作的未知数量SKAction
嘿,我在做SpriteKit回合制游戏的时候也遇到过一模一样的问题——CPU回合里要动态追加攻击动作,因为占领新区域后可能冒出新的攻击路径,提前构建好的SKAction.sequence根本没法应付这种不确定的流程。给你分享几个亲测好用的解决方案:
方案一:用递归调用动态生成攻击流程
这是我最常用的方法,核心思路是每次完成一次攻击后,重新判断是否还有可执行的攻击,如果有就再启动下一轮攻击动作,完全不需要提前构建完整的动作序列。
具体实现起来很简单,写一个负责执行单轮攻击+后续判断的函数,每次攻击完成后递归调用自己:
func runNextCPUTask() { // 第一步:检查当前是否还有可执行的攻击(包括新占领区域带来的新目标) guard let nextAttack = findNextValidAttack() else { // 没有攻击了,结束CPU回合 finishCPUTurn() return } // 构建单轮攻击的动作序列:模拟思考等待 + 执行攻击 + 递归判断 let singleAttackSequence = SKAction.sequence([ SKAction.wait(forDuration: 0.7), // 给玩家一点视觉缓冲时间 SKAction.run { [weak self] in self?.executeAttack(nextAttack) // 处理攻击逻辑:移动部队、占领国家、更新UI等 }, SKAction.run { [weak self] in // 攻击完成后,立刻检查是否有下一次攻击 self?.runNextCPUTask() } ]) // 启动这一轮攻击 self.run(singleAttackSequence) } // 辅助函数:查找下一个有效的攻击目标 func findNextValidAttack() -> Attack? { // 这里写你的判断逻辑:遍历CPU控制的所有国家,检查是否有可攻击的敌方目标 // 重点要包含刚占领的国家的新攻击路径哦 } // 执行具体攻击操作 func executeAttack(_ attack: Attack) { // 比如:播放攻击动画、更新游戏数据(占领国家)、刷新地图显示等 } // 结束CPU回合,切换到玩家回合 func finishCPUTurn() { // 这里写回合切换的逻辑:启用玩家操作、显示提示等 }
为什么这个方法好用?
- 完全动态:每次攻击完成后都会重新评估攻击可能性,新占领的区域带来的新路径会被立刻检测到
- 依赖前置动作:只有前一轮攻击完全执行完毕(包括等待、攻击逻辑),才会进入下一轮判断,不会出现动作重叠
- 代码简洁:不需要维护复杂的动作队列,递归逻辑清晰易懂
注意事项
- 一定要用
weak self避免循环引用,防止内存泄漏 - 调整
wait的时长,让CPU的操作流程看起来更自然,不要太突兀 - 在
findNextValidAttack里要确保正确处理刚占领的国家,比如攻击完成后立刻更新国家的归属状态,这样下一轮判断才能拿到最新的数据
内容的提问来源于stack exchange,提问作者TommyBs
相关产品推荐
相关产品推荐

