2

One of Apples videos on best practices with SpriteKit covers using batching to limit the draw calls. It then references using texture atlases in a way so that you can draw multiple different textures at the same time.

Can someone explain how I accomplish this?

See video: https://developer.apple.com/videos/play/wwdc2014/608/

at 22:22 in the presentation.

Might need to watch from 20:00 - 23:00 to get the full picture.

How do I get it to draw these helicopters in 1 draw pass?

Additional question. How do I get this same affect without code? Adding the helicopter sprites and assigning textures in the sks file?

Discoveringmypath
  • 1,049
  • 9
  • 23
  • 1
    Thanks for asking this again, as it helped me too. In my previous answer (https://stackoverflow.com/questions/44479805/issues-with-batch-drawing-with-atlas-files-and-spritekit) I didn't create the SKTextureAtlas. I just assumed having images in an .atlas folder will be enough. Will test it on my spritekit game in a few days and I'm sure my draw calls will be less too. – JohnV Jun 12 '17 at 02:22
  • Glad it helps... All about helping the community out! – Discoveringmypath Jun 12 '17 at 02:45

1 Answers1

3

First, create a texture atlas and add it to your project

  1. create a folder with a .atlas extension in your project directory
  2. add the helicopter parts images to the folder
  3. add the folder to your project (by right clicking in the Xcode's File Navigator and selecting "Add Files to "[Your Project]..." option)

Load the texture atlas by adding the following to didMove(to view:SKView):

let atlas = SKTextureAtlas(named: "helicopter")

and then create a texture for each part

let body = atlas.textureNamed("body.png")
let rotor = atlas.textureNamed("rotor.png")
let missiles = atlas.textureNamed("missiles.png")

Lastly, assemble the helicopters with the parts. The zPosition of each part determines the order in which they are drawn.

    let startX:CGFloat = -200

    for i in 0...10 {
        let helicopterBody = SKSpriteNode(texture: body)
        helicopterBody.zPosition = 100
        helicopterBody.position = CGPoint(x: startX + CGFloat(i*40), y: 0)

        let helicopterRotor = SKSpriteNode(texture: rotor)
        helicopterRotor.position = CGPoint(x: startX + CGFloat(i*40), y: 0)
        helicopterRotor.zPosition = 200

        let helicopterMissiles = SKSpriteNode(texture: missiles)
        helicopterMissiles.position = CGPoint(x: startX + CGFloat(i*40), y: 0)
        helicopterMissiles.zPosition = 0

        addChild(helicopterBody)
        addChild(helicopterRotor)
        addChild(helicopterMissiles)
    }

Show the draw count by adding the following to GameViewController:

view.showsDrawCount = true
0x141E
  • 12,613
  • 2
  • 41
  • 54
  • Thank you for the code, I hadn't thought about this method, but it works perfectly. I edited my question if you can take a look. Is this possible without code? just adding sprites to the sks file? Because that is where I'm having issues... – Discoveringmypath Jun 11 '17 at 15:22
  • Using your method, I can create the sprites in the sks file, but I have to leave the texture blank, and then assign the sprite the texture in code. It works, but it is hacky at best because I have to reference all sprites by name from code and my sks file looks crappy because they are just red squares instead of the actual textures. It should be possible to do this same method without code, but I'm unable to figure out how to get it to work. – Discoveringmypath Jun 11 '17 at 16:28
  • I think your answer is great if I'm going to be generating new sprites from code, but I would prefer to harness the sks files to build my levels in a visual way and still get the added benefit of less draw calls. Either way I appreciate the help as I will definitely need to use this method in the future. – Discoveringmypath Jun 11 '17 at 16:28
  • 1
    You can build a helicopter in the scene editor by adding three sprite nodes, one for each part, and setting the `texture` properties to the images in the atlas and assigning the appropriate `zPosition` for each sprite. If you build multiple helicopters in the editor, they will render in a single pass as long as the textures are in the same atlas. – 0x141E Jun 11 '17 at 16:52
  • In the scene editor, it will render each texture at a time. So it will draw the missile, then body, then the rotor; total of 3 draws. Now I can create 10 helicopters and it will draw all 10 with 3 draws, so the batching is working... but with the atlas file, I would expect to see it done in 1 draw pass, right? – Discoveringmypath Jun 11 '17 at 16:55
  • I just created two helicopters with multiple textures in the scene editor and they render in a single pass. – 0x141E Jun 11 '17 at 16:58
  • Is there anything extra that you did? because I can't get that to work on my end... I have showdrawcount set to true, I have default blend modes for all sprites, I have ignoresiblingorder set to true... Is there anything else I need to get this to work? – Discoveringmypath Jun 11 '17 at 17:00
  • Is your scene completely empty except for the helicopters? – 0x141E Jun 11 '17 at 17:01
  • Well I created a brand new project, and I just used 4 different images that I had instead of the helicopter... I also have 1/2/3x images per image... – Discoveringmypath Jun 11 '17 at 17:03
  • I tested without the 1/2/3x images and just 1 image per texture and same results... – Discoveringmypath Jun 11 '17 at 17:07
  • It must of been some issue with my project. Maybe there were remnants of images in my project files. I did a clean, closed and reopened Xcode and it worked... Man yesterday I was banging my head trying to figure out what was going on... damn... Anyways, Thank you for the help!!! – Discoveringmypath Jun 11 '17 at 17:30
  • It's 2020... I'm using a 'spriteatlas' (as they appear to be called now), and I'm seeing a big difference in performance between an actual device (iOS 12 iPhone 6) and Simulator (iOS 13.3). On the device, I get 1 draw call. In the simulator, I get as many draw calls as the number of unique textures being used, even though all textures share the same atlas. The Simulator frame-rate also tanks – Womble Jul 18 '20 at 01:19