实现可点击形状的最佳方法是什么?

时间:2017-06-09 23:15:07

标签: ios objective-c swift sprite-kit core-graphics

我正在构建一个提供可编辑画布的应用程序,类似于photoshop或Illustrator(目前使用SpriteKit)。在您显示大量节点(1000+)时,我遇到了一些性能问题。

目前,我的SKScene上有SKShapeNodes。他们目前没有任何图像,只是填充了一种颜色。它们的形状路径(CGPath s)从圆形到贝塞尔路径不等。每个形状当前都有一个SKPhysicsBody,其路径与用于检测水龙头的渲染形状相同。

性能问题可以通过以下方式描述:

  • 添加1000个节点(圆圈)时速度慢,每个节点使用大约0.1mb的内存
  • 移动1000个节点(圆圈)时速度慢
  • 从1000个节点(圆圈)生成纹理时速度慢

禁用PhysicsBodies 不会显着提高性能,但确实可以提高CPU负载(从常数60%跳到1%左右)

大多数用户不会使用1000个节点,但我希望实施最佳解决方案。

我想要的是两个有两层:

  • 渲染图层,我希望能够使用笔触和填充渲染CGPath(最好在其他小东西中选择笔触端盖样式)< / LI>
  • 互动图层,我希望能够检测CGPath内的点按,并使用一种颜色来指示CGPath,以指示突出显示。

如何实现这个或类似的解决方案,以提高我渲染1000个圆圈的速度?

1 个答案:

答案 0 :(得分:2)

不要使用SKShapeNode,每个shapenode需要1次绘制调用。您可以创建一个形状,然后在将其添加到场景之前将其“转换”为SpriteNode:

func shapeToSprite(_ shape: SKShapeNode) -> SKSpriteNode {
  let sprite = SKSpriteNode(texture: SKView().texture(from: shape))
  sprite.physicsBody = shape.physicsBody // Or create a new PB from alpha mask (may be slower, IDK)
  shape.physicsBody = nil
  return sprite
}

override func didMove(to view: SKView) {
  let shape = SKShapeNode(circleOfRadius: 60)
  addChild(shapeToSprite(shape))
}

如果您需要通过缩放或SKWarpGeometry无法编辑形状的大小/形状,这会很糟糕

要检测这样的点击,您只需要1,为SpriteNode设置名称然后在touchesBegan中查找,或者2,将SpriteNode子类化并覆盖它的touchesBegan。

此外,如果您只需要一个静态图像,您可以将数千个节点咬合到1个纹理上。 Sprite Kit: A Lot of sprites (1000+) with Bit Blitting

http://www.sdkboy.com/2014/01/spritekit-bit-blitting-by-drawing-to-a-texture-for-performance-optimization/

因此,如果您不需要每个节点都可以随时触摸,那么您可以在不使用physicsBodys之间切换,或者将图层从bitblitted切换为活动。