合并或展平后台节点以提高游戏性能?

Merging or flattening background nodes to improve game performance?

我希望能够通过某种方式 "flattening" 我的后台节点来提高我的游戏性能。


This youtube video demonstrates how I build up my background graphics.


但是,我的背景图片是这样设置的。

我使用了两个像邮票一样的纹理然后重复。 在这种情况下......一个带有雪顶的山脉纹理...... 没有雪的山纹理。 我改变了这些邮票的 zPosition 以获得 "layering" 效果。

然后我使用 "fills" 这只是纯灰色的 SKSpriteNodes 来覆盖需要灰色填充的部分。

例如添加填充节点之前

然后在顶部添加带有 alpha 的彩色屏幕,使山看起来褪色。

例如前

例如后


游戏有时会死机...但是当我删除这些图形时它并没有死机。

有没有一种方法可以通过在加载场景时基于 zPosition 合并或展平我的背景图形节点来提高性能? 我该怎么做?

这会提高性能吗? 或者在我的案例中提高性能的最佳方法是什么?

我觉得这个问题很相似... Merge all SKSpriteNode children into a single SKSpriteNode

但是,我如何在 Swift 中执行此操作并考虑 zPosition 和 alpha,这样我就不会丢失分层效果?

您可能想做的事情:

将前景和背景分离到单独的 SKS 文件中,然后加载它们 通过 SKReferenceNode

进入您的主 SKS 文件

使用 view!.texture(from: node)

通过代码将这些 SKS 文件转换为纹理而不是 SKReferenceNodes

确保您的地图集不会以增加抽奖次数的方式被分解

以并非所有节点都在场景中的方式设计您的代码,节点越多,您的代码就越慢。

如果您有 SKPhysicsBody 个,请尽量少用。这可以通过将多个物体与 SKPhysicBody(bodies:) 合并在一起或创建 1 个 body 以及围绕多个 objects.

的多边形来完成

此外,如果您的身体没有通过物理运动(不是 SKActions),请确保 isDynamic 设置为 false

如果您是 运行宁 SKAction,请确保尽可能少地使用这些内容。比如你有4个不同的节点以每秒10点的速度向左移动,你可以把这4个节点放到一个parent节点中,运行在parent节点上的动作

好的,这是您现在拥有的示例.. 这里的所有节点都是这样的:

如何轻松执行 bitblit 是将所有这些移动到一个名为 "background"

的新空节点下

现在转到您的 swift 文件,并为我们将在代码中创建的新节点设置一个占位符变量

class GameScene: SKScene {

  var blitBackground = SKSpriteNode()

  override func didMove(to view: SKView) {

  }

}

现在,添加这个方便的功能,如果需要,您可以在所有项目中使用它:

func blit(from node: SKNode) -> SKSpriteNode {
  return SKSpriteNode(texture: SKView().texture(from: node))
}

下面是我们将用来初始化 bitblit 背景并从游戏中移除滞后背景的方法:

  func blitTheBackground() { // use in didMove
    let laggyBackground = childNode(withName: "background")!
    blitBackground = blit(from: laggyBackground)
    laggyBackground.removeFromParent()
    addChild(blitBackground)
  }

这是完成的场景:

class GameScene: SKScene {

  var blitBackground = SKSpriteNode()

  func blit(from node: SKNode) -> SKSpriteNode {
    return SKSpriteNode(texture: SKView().texture(from: node))
  }

  func blitTheBackground() {
    let laggyBackground = childNode(withName: "background")!
    blitBackground = blit(from: laggyBackground)
    laggyBackground.removeFromParent()
    addChild(blitBackground)
  }

  override func didMove(to view: SKView) {
   blitTheBackground()
  }

}

并将节点数从 10 个减少到 4 个...希望它对您的绘制计数也有帮助!!

注意,此方法对形状节点非常有效!!

如果需要在循环中执行此操作,请务必将其放在自动释放池中,以确保内存在使用后被释放。从视图创建纹理会占用大量内存,因此如果不小心,可能会出错。

for i in 0..<5
{
    autoreleasepool{
        let laggyBackground = childNode(withName: "background\(i)")!
        blitBackground = blit(from: laggyBackground)
        laggyBackground.removeFromParent()
        addChild(blitBackground)
    }
}