While writing the Learn Cocos2D book I was surprised to find that Cocos2D’s CCSpriteBatchNode was only able to increase the performance of several hundred bullet sprites on screen by about 10-15% (20 to 22.5 fps). I wanted to re-visit that scenario for a long time because as far as I understood, the more sprites I was drawing the greater the impact of CCSpriteBatchNode should be.
But even Cocos2D’s own sprite performance tests (compare columns 9 and 10) revealed a performance difference of under 20% (39 to 42 fps). It’s only when all sprites are scaled and rotated, or most of them are outside the screen area, that sprite batching seems to have a bigger impact (25 to 60 fps). Surely that scenario is not applicable to most games. So I started investigating.
Chapter 8 - Shoot ’em Up
This chapter will finish the shoot ’em up game. There will be enemies and powerups. It raises the issue of good code design when certain things like shooting and moving are common to all objects while other things such as what to shoot and where from and to depend on who is shooting. And then to determine who is hit by whose bullets.
Of course no shoot ’em up game is complete with a boss monster that takes a couple hits to kill. So it’ll need a healthbar. At the end of the chapter this shoot’ em up should be a fully playable game, with Chapter 9 complementing it with visual effects by using the cocos2d particle system. But I’m getting ahead of myself here.
Summary of working on Chapter 7 - Scrolling With Joy
Once again I renamed the chapter a bit since it’s divided into two parts: a parallax, infinitely scrolling background and input via SneakyInput, featuring a fire button and an analog thumbstick respectively at the end changed to a 8-way digital pad.
The parallax scrolling background consists of several bands or stripes which were created on different layers each in Seashore and then saved as individual 480×320 images. They were then added to the Texture Atlas by Zwoptex. The cool thing about this is that Zwoptex preserves the original image’s size while stripping away all transparent parts. So the images take up little space in the Texture Atlas but in game you don’t have to position them individually, you’ll simply place them at the center of the screen.
To achieve the endless scrolling effect two of each image where added side-by-side to each other, with one flipped on the X axis so the images align neatly. Whenever one image has scrolled outside the screen it is moved back to the right side of the screen. At the end I also fixed the vertical flicker lines which can appear due to round-off errors when moving the sprites. And of course they all are drawn with a CCSpriteBatchNode.
The SneakyInput fire button allows continuous shooting and faster shooting when you just tap it, while the thumb stick controls the ship’s movement in both analog and digital (8-way) variants. The Ship class’ setPosition method is overridden to keep the player’s ship within screen boundaries at all times. Finally an extension class gives SneakyInput the same autorelease initializers used by cocos2d, and adds another good example of just how useful Objective-C categories can be.
Chapter 7 - Side-Scrolling Shooter
The shooter game will be controlled with a virtual joystick using SneakyInput. The background parallax scrolling will be implemented not with the CCParallaxLayer, as it does not support endless scrolling (as far as I know, please correct me if I’m wrong). The rest will be gameplay code, mostly spawning enemies, moving them and collision tests.
The chapter will be submitted on Friday, August 13th. Yup, Friday the 13th. Scary.
Summary of working on Chapter 6 - Sprites In-Depth
I decided to rename this chapter to Sprites In-Depth as it deals mostly with Sprites, Sprite Batching (formerly known as Sprite Sheets), Texture Atlases and Zwoptex as well as general texture memory management. All the while laying the foundation for the game to be made in Chapter 7.
While working on this chapter I noticed that it’s awfully complex to create a CCAnimation class, especially if you’re not using a Texture Atlas. So I decided to illustrate how to add helper methods by adding them via a Objective-C Category to the CCAnimation class. Now you can create a CCAnimation with just one line of code, instead of around ten.
Once more I created some of my now famous doodle artworks. If anything this should show that even a programmer can do art. Or, well, at least something that vaguely resembles art.
I was a bit surprised by one thing though, and that is how little the use of the CCSpriteBatchNode contributed to the framerate in this particular case. I added all the bullets to a CCSpriteBatchNode and found only a 15% increase in performance, it went up from 45 fps to a little over 50 with all those bullets flying. I sort of expected a bigger impact from previous experiences.