We're at the start of week 3 of the new game, Destroy More Cars, which unsurprisingly is the sequel to our Destroy All Cars game.
It's the first outing for our blitter engine, so I thought I'd touch on that quickly.
If you've read the previous post you'll see there that I recommend a blitter engine for CS5 / iPhone development so I've been working on ours so it's there ready for the next project.
At the core of the blitter is the Canvas class. This holds the bitmap we're plotting to, does the lock / unlock thing, clears the canvas when needed ( By copying the background bitmap on there rather than fillRect ) and calls the children display objects.
Next up is the PlayField class. These are in effect layers. When I code I usually create sprites as holders and add these to the stage in order to simulate IDE layers, the PlayField class is just the same really.
At the bottom of this hierarchy are the building blocks, the Bobs. These are just simple sprites that are plotted to the canvas using copyPixel ( I've started work on a ComplexBob class which uses draw(), slower but it supports all the things that copyPixel can't, such as scale, alpha, rotation etc. Pain in the arse to code though, so slightly on the backburner and I'm just using bitmap's as simple sprites in the mean time ).
To make this truly useful I've tried to copy the existing DisplayObject as closely as possible, so for example if we've got an animated bob we can use bob.gotoAndPlay(bob.currentframe+1), to add a bob to a playField it's as simple as playField.addChild(bob) etc.
Depth sorting is in there too which makes life so much simpler ( The PlayField class is basically a list manager, making sure the bobs are always in the order we want. That's all depth sorting is really, just specifying what order to plot things in ).
One thing I stumbled upon the other day was the very sexy stage.invalidate(); To put it simply it's a way of flagging up the stage has been made dirty ( Altered ). If you have a stage.addEventListener(Event.RENDER,update);
listener, then when a stage.invalidate() is called at the end of the frame just before plotting everything our update method is called ( Via the RENDER event ). This means we don't have to call the update method as we usually would during our enterFrame main loop, in effect it handles itself, like the real display list does.
With using that, Vector lists which we loop through, lock / unlock etc. it all runs pretty quickly. Benchmarks I find are always a bit throwaway unless they're part of a really detailed set of comparisons, it's so easy to put a bit of spin on them to prove your code is the fastest.
Obviously I can't be bothered to do proper benchmarks, so prepare for some spin. DMC is running 6 layers of parallax on a 640x480 screen. It's got a handful of box2D objects ( The images are bitmaps rather than plotted via the blitter ) . In the screen grab above I think it's running 70 rain particles, but when I was testing I cranked that up to 500 just to push things. We've also got up to 80 glass particles ( Those little blue pixels at the top right of the grab ), soft particles for the smoke ( It's the first time I've used for particles for that as opposed to just pre-rendered images ) and there are 20 bits of debris spinning around in 3D, along with car door which rotates around in 3D too. With all that running it didn't drop a frame, stayed at a rock solid 35fps.
I think damage maps may speed things up in certain situations, but I'm more than happy with how it's performing right now, so that can be done if it's needed.
And that dear reader is how our blitter works.