如何使用动画回收 SKSpriteNode

Posted

技术标签:

【中文标题】如何使用动画回收 SKSpriteNode【英文标题】:How to recycle SKSpriteNodes with animations 【发布时间】:2016-09-13 20:49:10 【问题描述】:

我正在使用 Swift 和 SpriteKit 制作我的第一款游戏,我遇到了无数 CPU 问题,在这些问题中,我在玩了几分钟后就接近 100% 的 CPU。看起来这不应该发生,因为我一次只画 20 多个动画敌人。虽然这不是唯一的问题,但我相信实例化我的敌人类在很大程度上导致了这种过度使用。

在我的代码中,我每隔几秒就实例化一个新的敌人外星人。我相当确定我正在正确删除它们 - 无论是在接触时还是在它们移出屏幕时。所以我相信我的下一个尝试应该是尝试回收它们,而不是不断地完全删除和添加它们。

我正在添加:

func addNormAlien()
    let mult = normAlienMultiplers

    let alienInst = normAlien(startPos:CGPoint(x: 10,y: 10), speed: random(UInt32(10), max: UInt32(50))*mult[0])

    let yStart = random(UInt32(alienInst.size.height/2), max: UInt32(size.height-alienInst.size.height))
    alienInst.position = CGPoint(x:size.width+alienInst.size.width/2, y:yStart)

    addChild(alienInst)
    totalNodes+=1

并使用一般声明删除:alien.removeFromParent() 在两种联系方法中,如果它的 x 位置超过某个点,则在更新中。

我在想我可以创建一个适合某个最大数量的数组(或队列?),然后我可以将它们推开和推开。有没有合适的方法来回收这样的 SKSpriteNode 子类?附:在 iPhone 上测试时,CPU 使用的适当范围是多少?

【问题讨论】:

我不确定你现在是否想这样做。由于这是您的第一款游戏,并且之前已经回答了您的一些问题,您希望遵循 K.I.S.S 模式。鉴于您只有“20 个”敌人,那么这表明您的敌人数量超过 20 个,或者您在代码中做错了事。即使你去一个对象队列,你可能会获得一些性能提升,但你的代码不会被修复,你会遇到其他问题。我之前就如何解决 CPU 问题提出了一些建议,但我有点怀疑你是否都做到了。 【参考方案1】:

我说你应该看看at the prototype pattern。您基本上只在第一次创建每个敌人并克隆它们以在游戏中使用。至少这应该减少文件系统交互(加载纹理等......)。

【讨论】:

我想我不明白——“克隆”过程不是一样密集而且还保存状态吗?同样对于像这样一个相对简单的 2D 游戏,您认为设备上的适当 CPU 使用是什么? 我假设您每次创建敌人时都从文件系统重新加载纹理。文件系统交互通常很慢。通过创建一个原型并且只加载一次并且每次你需要使用它们时只克隆敌人,你可以将其减少为内存交互,这样会更快。或者,您可以将所有纹理预加载到静态类中,这可能是一种更简单的方法。 您还应该检查节点计数(SKScene 上的属性)以确保正确删除节点。 Wrt CPU 使用,SpriteKit 应该能够轻松处理您的用例,只要您不使用 SKShapeNodes。 SKShapeNodes 非常慢,应该主要用于调试。

以上是关于如何使用动画回收 SKSpriteNode的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SpriteKit 中使用不同大小的纹理制作动画

如何在事件发生后在给定约束内返回 SKSpriteNode?

如何围绕节点的 Y 轴旋转 SKSpriteNode?

如何通过 Sprite Kit 中的 CGPoints 数组制作动画 - Swift

在触摸时将动画添加到 SKSpriteNode (Swift)

Swift - 使用纹理数组更改 SKSpriteNode 纹理