Reputation: 1542
I am using SpriteKit to render a large (20 x 20) dot grid that looks like this:
I'd like to highlight rows or columns based on user input. For example, I'd like to change rows 1-10 to a red color, or columns 5-15 to a blue color.
What is the most performant way to do this?
I've tried:
GridNode
based on the column it's in (e.g. @"column-4
). Then use enumerateChildNodesWithName:
with the string as @"column-n"
, changing the color of each node (by changing SKShapeNode
setFillColor:) in the enumerate block.I've tried making the GridDot
class an SKEffectNode
with shouldRasterize:
set to YES
. I've tried both an SKShapeNode
and a SKSpriteNode
as its child. I've also tried taking away the SKEffectNode
parent and just render an SKSpriteNode
.
Each of these options makes my whole app lag and makes my framerate drop to ~10 FPS. What is the correct way to change the color/alpha of many nodes (without dropping frames)?
At its heart, the issue is rendering this many nodes, yes?
Upvotes: 4
Views: 1687
Reputation: 1995
In contrast to @amobi's statement, 400 nodes is not a lot. For instance, I have a scene with ~400 nodes and a render time of 9.8ms and 9 draw calls.
If you have 400 draw calls though, you should try to reduce that number. To determine the amount of draw calls needed for each frame rendered, implement (some of) the following code. It is actually taken from my own SpriteKit app's ViewController class which contains the SpriteKit scene.
skView.showsFPS = YES;
skView.showsNodeCount = YES;
skView.showsDrawCount = YES;
I recommend using SKView's ignoresSiblingOrder
. This way, SKSpriteNodes with equal zPosition
are drawn in one draw call, which (for as many nodes/draw you appear to have) is horribly efficient. Set this in the -viewDidLoad
method of the SKView's ViewController.
skView.ignoresSiblingOrder = YES;
I see no reason to burden the GPU with SKEffectNodes in this scenario. They are usually a great way to tank your frame rate.
Basic performance issues mean you have a CPU or a GPU bottleneck. It is difficult to guess which you're suffering from with the current information. You could launch the Profiler, but Xcode itself also provides valuable information when you are running your app in an attached device. FPS in the Simulator is not representative for device performance.
Upvotes: 3
Reputation: 2635
When I faced similar performance problems while using SKShapeNode I came up with this solution:
SKShapeNode
with required path and color.SKView
's method textureFromNode:crop:
to convert SKShapeNode to an SKTextureSKSpriteNode
from a textureSKSpriteNode
in your scene instead of SKShapeNode
SKSpriteNode
's texture
propertyIf you have a limited set of collors for your dots, I think this aproach will fit fine for your task.
Upvotes: 3