2

I'm building a game in SpriteKit and have recently ran into problems with my frame rate continually dropping to 50-45 from 60 only in GameSceneand a couple second lag upon opening the GameScene from my StartScene. I have tried a bunch of different things and I believe one of my main problems has to do with animating a SKSpriteNode subclass that spawns very frequently, when I stop animating them and instead use a single texture the frame rate stays at 60. I previously posted about preloading textures into SpriteKit, and received awesome answers but I may have not fully understood. At this point I have all of my GameScene textures in a single Atlas and I load them all in by creating constants for each right before my GameScene:

//Preload textures of GameScene before running it
let alienTexture1 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture1")
let alienTexture2 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture2")
...

class GameScene: SKScene, SKPhysicsContactDelegate {

I know that I'm supposed to use:

SKTextureAtlas(named: "YourTextureAtlasName").preloadWithCompletionHandler { 
// Now everything you put into the texture atlas has been loaded in memory
}

to preload the textures but I'm not sure what goes in between the brackets and when a line like let alienTexture1 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture1") is supposed to be called. These textures are then called inside of the init of some Alien SKSpriteNode subclasses that I have. I'm not understanding something because the preload clearly isn't working properly. I'm also not sure what to do about the lag when switching to the GameScene but I imagine it also has to do with my way of loading in textures at the beginning with all of those let statements. Any advice would be great.

I have looked at other questions on this subject and felt that this was specific enough that it wasn't a repeat.

Community
  • 1
  • 1
muZero
  • 948
  • 9
  • 22

1 Answers1

0

I was confused on this as well and I am by no means an expert but essentially preloading textures just means you store them in an array/property that will not get deallocated.

I dont really use the SKTextureAtlas("").preloadWithCompletionHandler method. I believe the idea is basically the same.

For example you can create a static texture loading class

 class Textures {

      static var alien1 = [SKTexture]() // array off all alien 1 textures


      static func preloadAll() {
           loadAlien1()
           ...
      }

      // Alien 1
      static func loadAlien1() {

           // Get atlas
           let alien1AtlasName = "Your atlas name"
           let alien1Atlas = SKTextureAtlas(named: alien1AtlasName)

            // Loop through images in atlas and append to alienTexture property
           // In this case there is 2 images in the atlas)
           // Images should be appended by _1 , _2 etc 
           for image in 1...2 {
               let textureName = "\(alien1AtlasName)_\(image)"
               let texture = alien1Atlas.textureNamed(textureName)
               alien1.append(texture)
           }   
      }
 }

When your app launches in appDelegate or GameViewController preload the textures

 Textures.preloadAll()

If you have a lot of textures and you want to keep memory usages low just preload the Textures you initially need and load other textures for other levels later.

  Texture.loadAlien1()

Than you can run the animations on your alien 1 characters from your subclass or SKScene like this

let textureAnimation = SKAction.animateWithTextures(Textures.alien1, timePerFrame: 0.3)
alien1Sprite.runAction(SKAction.repeatActionForever(textureAnimation), withKey: "Alien1AnimationKey")

If you need to clean your textures, incase you no longer need them or if your app gets a low memory warning you just empty the arrays.

 Textures.alien1.removeAll()

In regards to performance, you should also store your atlas in xCode asset catalogue, which is a new feature in xCode 7, instead of a folder in your project.

Hope this helps

crashoverride777
  • 10,581
  • 2
  • 32
  • 56