Writing a simple arcade game for a handheld device (and even then to be executed through a web browser) is quite different from the luxury of writing for the desktop. Not only do you have to consider the scale and colour of everything but you have to be careful with just how much you throw around.
I no longer use DIVs and IMG files instead opting to use the Canvas element courtesy of HTML5.
When I first started writing with the iPhone in mind I thought I had run in to some serious canvas limitations. I was essentially doing the same thing with the same routines but somehow the approach seemed to yield a far lower frame rate. It didn’t make sense to me since iPhone is pretty powerful, right ?
I scratched my head. Could it really be that wiping the entire screen and then redrawing everything (regardless of whether it has moved) was such a drain on the device’s performance ? I certainly didn’t want to go to the trouble of detecting which sprites occupied certain regions before clearing the canvas down. Besides that would probably be an even bigger ask.
But the it dawned on me that my methods were not ideal.
I’ll try to explain.
When I populate the game with entities I essentially pick them from a pot.
During initialisation I build arrays of entities. In most cases for things like explosions I create a pot of about 50 objects. Same goes for alien bombs and player lasers. I also tend to throw around spark effects and various other niceties.
When the game loop requests such an entity it enters a loop and looks for the object that isn’t currently visible.
Where there is a lot going on on-screen this can stretch to pretty much the array length.
When it finds an object to use it simply breaks out of the loop and returns the object.
In total I was probably asking my game loop to step through an array of around 300 elements 20 – 30 times a second.
I then pass these objects in to the relevant method – draw(), move(), collision() – and have each method handle the situation in its own container.
Where the object being passed is not visible (i.e. it’s been destroyed / picked up, left the screen boundaries or hasn’t yet been used) I simply back out of the method.
if (!object.visible) return;
This works well and obviously saves a huge amount of crunching when you’re trying to perform the same actions several times a second.
So I put together a couple of tests.
In one corner I had my current and unedited game file.
In the other corner I had a new game file with the array sizes drastically reduced. A small and insignificant changes you might think !
Both files were running flat out.
I ran them both and took the diags.
Both were running in Firefox 3.6.
The first file gave me around 77 FPS.
The second (with the reduced array sizes) gave me around 90 FPS.
I’ve yet to test this on the iPhone but I would hope to see frame rates increase from the 16 – 18 FPS that I was experiencing earlier.
Something around 25 FPS ought to be acceptable for a simple Space Invader game.
I’m rather pleased to see this since the alternative was alter the game’s design.
It’s important for me to have plenty to shoot at. The first thing to go would have been the fancy sparks and screen full of entities. Never the aliens and explosions.
I also took the decision to reduce the amount of lasers that the player can launch and have on screen at any one time. It’s not ideal but will probably make for a more intense game.
Finally I dropped the alien bomb pot from 30 to 4. Only 4 alien bombs on screen at once !
To counter this I ditched the idea of an energy bar that gets depleted with every hit from an alien bomb.
Instead I went for the classic one hit and you’re out a la Space Invaders / Galaga etc.
Again this tends towards a more intense experience.
So all in all a worthwhile exercise. It sets me up a bit more for crafting such games for mobile devices. Something I needed to do if I’m to maintain the amount of games I’m hoping to produce each month.