Search code examples
iosobjective-cswiftsprite-kitframe-rate

Spritekit - dynamically adding children slows performance


I'm trying to figure out how to optimize my game. I have a lot of turrets etc shooting out physics bodies. The game is playable but can dip into 50 or 45 fps. I've figured out that it is related to adding objects to my scene on the fly.

for example. when my turret is shooting it runs this code

func shootBlaster(){
    let blaster = Projectile(color: SKColor.cyanColor(), size: CGSize(width: convertNum(3), height: convertNum(3)))
    blaster.name = "blaster"
    blaster.physicsBody = SKPhysicsBody(rectangleOfSize: blaster.size)
    blaster.physicsBody!.categoryBitMask = CategoryEnemyProjectile
    blaster.physicsBody!.contactTestBitMask = CategoryShip | CategoryShipShield
    blaster.physicsBody!.collisionBitMask = 0



    let fireAction = SKAction.runBlock({
        let angle = self.turret.base.zRotation + self.zRotation
        let velocity = CGPoint(angle: angle) * convertNum(420)
        let vector = CGVectorMake(velocity.x, velocity.y)
        let blas = blaster.copy() as Projectile
        blas.wpnDmg = 10
        blas.position = self.gameScene.gameLayer.convertPoint(self.turret.barrelPos, fromNode: self.turret.base)
        self.gameScene.gameLayer.addChild(blas)
        blas.physicsBody!.velocity = vector
        blas.zRotation = blas.physicsBody!.velocity.angle

        blas.runAction(SKAction.removeFromParentAfterDelay(1))
    })

    let recoilAction = SKAction.moveByX(-5, y: 0, duration: 0.08)
    let reverseRecoil = recoilAction.reversedAction()

    self.turret.barrel.runAction(SKAction.repeatAction(
        SKAction.sequence([
            recoilAction,
            fireAction,
            reverseRecoil
        ])
    ,count: self.blasterNum))

}

you can see that I'm adding a "blaster" inside of each of the fireAction blocks. I've noticed games with better performance are rarely adding children at runtime. It seems best to have everything pre-loaded. It makes sense that loading resources during runtime would put a strain on things, but what is the alternative? Do I need to add everything to the scene ahead of time and somehow hide and show it?


Solution

  • With any kind of shooting game where you have numerous projectiles you want to utilize "pooling". Create a pool of projectiles and reuse them as opposed to creating new ones when you need them.