10,000+ Sprites Animating And No Loss In Framerate Using iOS7’s SpriteKit

UPDATE: Upon further research into SpriteKit’s inner workings I’ve updated this post. Because SpriteKit automatically uses batch drawing where possible it is not always nessesery to draw the display hierarchy to a texture. I’ve found that SpriteKit can animate 10000 particles on screen at 60fps without blitting. If you are interested in blitting the display hierarchy for better performance check out my other post on drawing a node hierarchy to texture using textureFromNode in SpriteKit.

As you can see from the code below, it’s very simple to take advantage of SpriteKit’s native GL Batch drawing optimization. All that really needs to be done is reuse the same texture, and then all sprites added to the scene will be drawn in one pass.
There are many other tricks and optimizations that can be done, but it’s good to know that iOS takes care of the batch drawing natively. See this post for more info on undocumented inner workings of SpriteKit. Download the example project here.

- (void)setupParticles
{
    self.backgroundColor = [SKColor blackColor];
    
    // create the particle texture
    SKTexture *ledTexture = [SKTexture textureWithImageNamed:@"whitePixel"];
    self.canvasNode = [SKNode node];
    
    // cycle through and throw as many sprites into the node as you want
    for (int i = 0; i < 5000; i++) {
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithTexture:ledTexture];
        sprite.position = CGPointMake(arc4random_uniform(320), arc4random_uniform(568));
        sprite.colorBlendFactor = 1.;
        [self addChild:sprite];
    }
    
    self.sprites = [NSArray arrayWithArray:self.children];
    
}


-(void)update:(CFTimeInterval)currentTime {
    
    for (SKSpriteNode *sprite in self.sprites) {
        sprite.position = CGPointMake(arc4random_uniform(320), arc4random_uniform(568));
    }
}

9 comments

  1. That is some great info! Thanks 🙂 Could something like this be used to optimize physics bodies, allowing for 1000s(?) of colliding SKSpriteNodes?

    Reply

  2. Could you please specify what other optimizational tricks there are in your code? Thanks!

    Reply

    1. Hey Peter, I haven’t really included any tricks for optimization in this code, but most techniques revolve around the textures you are using. So using a texture atlas, or sprite sheet, for all your textures can mean they occupy less memory. Reducing the color depth of your sprite sheet from 32bit to 16bit can be a good idea if possible. Also reusing the same sprite/texture and manipulating it (tinting etc) instead of having multiple different textures, will mean they’re all drawn in the same pass. Using power of twos (2, 4, 8, 16, 32, 64, 128, 256..) for your sprite sheet size is a common optimization technique too. I use an app called TexturePaker, it’s really useful for placing all of your separate png textures into one spriteSheet at the optimum size.

      Reply

  3. Can you clarify where you’re seeing 60fps with this? Downloading your example code and running it directly shows 20fps for me. xcode 5.1.1, iOS sdk 7.1.

    Reply

    1. You have to be running on the device. The simulator doesn’t give realistic frame rates as it doesn’t use GL(someone correct me if I’m wrong about that). Generally the frame rate will be half of what it is on the device.

      Reply

  4. Thanks for this info. I was having a terrible time with SpriteKit performance on the iPhone 4, was trying everything to improve it. Using your code I was able to test the maximum performance of the iPhone 4 using SpriteKit and while it didn’t solve my problem, it showed that the hardware of the old iPhone 4 just wasn’t up to the task.

    Reply

  5. Hey, I’m wreating a game with SpriteKit. My architecture is to switch scenes with navigation of sotryboard.
    But when I pop viewController it’s not realising the memory. But all aobject are released.
    So my question is the graphic i had use in my previous scene are keeping in memory ?
    If yes so how to release them? If no what can take this memory ?
    Other question I got is that when I run animations and so on… I got memory warnings and app’s crash.
    I can’t display more then 2-3 animation with 100-200 sprites included to single one. But i heard that blizzard is using 500sprites for one animations and on the screen are multiple animations displayet and the same time. How they menage that ? what about memory ? How it’s working and not crashing ?
    Please help me. and contact me with my mail if u can.

    Reply

  6. Woah! I’m really enjoying the template/theme of this website.
    It’s simple, yet effective. A lot of times it’s challenging to
    get that “perfect balance” between usability
    and visual appearance. I must say you’ve done a
    very good job with this. In addition, the blog loads super fast for me on Internet explorer.
    Superb Blog!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *