Swift SpriteKit开发敌人生成移动时游戏短暂冻结问题求助
let waitForSec = SKAction.wait(forDuration: 1.2) 并不是卡顿诱因,SKAction的等待逻辑是非阻塞的,不会占用主线程运算资源,卡顿是spawnEnemyHorizon函数执行时的主线程阻塞导致的,可从以下方向排查修复:
- 检查
createEnemy方法是否重复加载纹理
绝大多数SpriteKit生成节点时的卡顿都来自纹理的重复IO加载:如果每次调用
createEnemy都实时从应用包读取陨石图片生成纹理,批量生成敌人时的多次磁盘IO会直接阻塞主线程。
修复方案:在场景初始化(如didMove(to view:))阶段提前预加载所有陨石纹理,存入全局纹理缓存数组,createEnemy时直接复用缓存的纹理生成节点,避免重复读取磁盘。
- 优化集合查询效率
代码中
positionForPlayer.contains(possitionArray[index])如果positionForPlayer是数组类型,每次contains查询的时间复杂度为O(n),当possitionArray元素较多时,循环内多次查询会产生大量冗余运算。
修复方案:将positionForPlayer改为Set类型(CGPoint本身支持哈希可直接存入Set),contains查询的时间复杂度会降到O(1),大幅降低循环运算开销。
- 修复节点泄漏问题
当前代码每次执行
spawnEnemyHorizon时仅调用enemies.removeAll()清空了数组引用,没有主动移除上一批还在场景中运行的敌人节点,长期运行会导致场景内节点数持续增长,渲染压力越来越大最终出现卡顿。
修复方案:在enemies.removeAll()之前先遍历数组调用所有敌人的removeFromParent(),主动释放无用节点,控制场景总节点数在合理范围。
- 验证逻辑绑定关系
可临时将
waitForSec的时长改为0.5测试,如果卡顿频率随生成频率升高而变高,即可确认卡顿完全和spawnEnemyHorizon的执行绑定,和wait计时逻辑无关。
内容的提问来源于stack exchange,提问作者Azmat

