I want to be able to improve my game's performance by somehow "flattening" my background nodes.
This youtube video demonstrates how I build up my background graphics.
But, I have my background graphics set up like this.
I use two textures like stamps and repeat then. In this case... one mountain texture with a snowy top... One mountain texture without the snow. I alter the zPosition of these stamps for a "layering" effect.
I then use "fills" which are just SKSpriteNodes of solid grey to layer over parts that need a grey fill.
E.g. Before fill nodes are added
A colour screen with alpha is then added on top to give the mountain a faded looked.
E.g. Before
E.g. After
The game sometimes freezes up... but it doesn't freeze when I remove these graphics.
Is there a way to improve performance by merging or flattening my background graphics nodes based on zPosition as a scene is loading up? How would I do this?
Would this improve performance? Or what would be the best way to improve performance in my case?
I think this question is similar... Merge all SKSpriteNode children into a single SKSpriteNode
But, how do I do this in Swift and take zPosition and alpha into account so I don't lose the layering effects?
Somethings you may want to do:
Separate your foreground and background into separate SKS files, and load them
into your main SKS file via SKReferenceNode
Convert these SKS files into textures instead of SKReferenceNode
s via code using view!.texture(from: node)
Ensure your atlas is not being broken up in a way that adds to the draw count
Design your code in a way that not all nodes are on the scene, the more nodes the slower your code becomes.
If you have SKPhysicsBody
's, try to use as few as possible. This can be done my merging multiple bodies together with SKPhysicBody(bodies:)
or creating 1 body with a polygon that goes around multple objects.
Also, if your bodies are not moving via physics (Not by SKAction
s) then make sure that isDynamic
is set to false
If you are running SKAction
s, make sure you use as few of these as possible. For example, if you have 4 different nodes travelling left at 10 points per second, you can put these 4 nodes into a parent node, and run the action on the parent node.
Ok so here is an example of what you have now.. all your nodes here like this:
How to execute the bitblit easily is to move all these under a new empty node called "background"
Now head to your swift file, and set up an placeholder variable for the new node we will create in code
class GameScene: SKScene {
var blitBackground = SKSpriteNode()
override func didMove(to view: SKView) {
}
}
Now , add this handy function that you can use in all of your projects if desired:
func blit(from node: SKNode) -> SKSpriteNode {
return SKSpriteNode(texture: SKView().texture(from: node))
}
and here is the method we will use to initialize our bitblit background, and remove the laggy one from the game:
func blitTheBackground() { // use in didMove
let laggyBackground = childNode(withName: "background")!
blitBackground = blit(from: laggyBackground)
laggyBackground.removeFromParent()
addChild(blitBackground)
}
Here is the completed scene:
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()
}
}
and it reduced the node count from 10 to 4... hopefully, for you it will help with your draw count too!!
NOTE, this method is EXTREMELY effective with shapenodes!!
If you need to do this in a loop, be sure to place it in an autorelease pool to be sure that the memory is freed up after it is used. Creating textures from the view uses a lot of memory, so you can expect to get errors if you are not careful with it.
for i in 0..<5
{
autoreleasepool{
let laggyBackground = childNode(withName: "background\(i)")!
blitBackground = blit(from: laggyBackground)
laggyBackground.removeFromParent()
addChild(blitBackground)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With