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

Most optimal method of implementing tappable shapes?

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

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

性能问题可以描述为:

禁用 PhysicsBodies 不会 显着提高性能,但会提高 CPU 负载(从恒定的 60% 跳到 1% 左右)

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

我想要的是两个有两层:

我怎样才能完成这个或类似的解决方案来提高渲染 1000 个圆圈的速度?

不要使用 SKShapeNode,每个形状节点需要 1 个绘制调用。您可以创建一个形状,然后 "cast" 将其添加到 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/

因此,如果您不需要每个节点始终可触摸,您可以在拥有和不拥有 physicsBody 之间交替,或者将层从 bitblitted 切换为活动。