In this article I want to share my experience in developing a dynamic game for iPhone using Flash and Adobe Air platform. But first of all, please sorry me for my English. That’s not my native language.
So, what is Air? Saying in a pair of words it is a platform that makes available to run flash applications on different devices – iOS, Android, Blackberry, even TVs. Beginning developing in Air I didn’t know anything about it. But that’s not a problem because in 95% Air application is similar to an ordinary Flash application.
So, my team and I decided to take our chance in making a game for iPhone. There was no objective to earn money. The first and main objective was to make an experiment and to find out if it is possible to make smooth dynamic games on Air for iOS.
We wanted to make our game as soon as possible, so we wanted some gameplay that:
- Would be simple, so we can make our game fast.
- Wouldn’t need many animated and moving objects because we was not sure it can be done smooth on iOS.
- Would use not common and cloned for 10 times gameplay.
- Wouldn’t need to make 100 different puzzle levels because we didn’t want to spend our time on that.
Also, we didn’t want to invent our own gameplay (and also didn’t have time for that), so we decided to clone some game.
After a few days of search we found our victim – game "Axe in Face".
Let the develop begin!
So, we started to work…
Developing on Air was easy. It is a regular Flash development with some minor modifications (in most cases in some device-specific functionality such as multi-touch, accelerometer, etc.)
So, let’s put flash develop apart and focus on iOS-specific troubles and hints.
That’s the main theme. All is about the performance when you’re developing something for a mobile phone. We wanted our game to look like native ones. To make smooth effects similar to other iPhone games. So, we’ve tried different technics and made our best to achieve it.
But, I need to say, that was not possible for everything.
So, we tried different graphics engines to put our sprites…
1. Flash engine, bitmap frames.
First of all, of course, no vector! Vector is very slow. You need to work with bitmaps only.
The first thing we tried was a simple flash movieclip with bitmap in frames.
Surprisingly it worked not so bad, but we wanted more…
2. Bitmap blitting.
Next thing we tried was bitmap blitting. This is a common method for desktop flash games. The idea is to make one bitmapData and to copy all your sprites into it, one by one. And after all show it on the screen.
This method works great on desktops but failed on iOS. It seems that memory operations are quite slow for now.
3. Advanced flash engine.
After some research I found out how to improve graphics performance and why standard flash engine didn’t work well. The idea is that if you want to animate your sprites fast, you need to store all graphics in memory.
When using standard flash engine it takes every new frame to memory every time it needs. So, every frame flash engine disposes old graphics and creates new, for new frame.
But all graphics is re-usable, so there’s no need to dispose it after usage.
First what we did is we loaded all our graphics data in a vector of bitmapData – each frame in its own bitmapData. Then we made Bitmap objects from each of frames and put all of them in our sprite MovieClip. So, sprite contained all its frames in the same time in one single frame. The next we needed to do is to switch visible property for them and to show only one frame a time.
The idea was that all graphics was available at once, and used frames were not killed after showing. So, no creating new graphics and no disposing used.
That worked well but could be improved.
The next improvement stage was that we made a single Bitmap object and just swapped bitmapData field for it. Something like: main_bmp.bitmapData = bd_frame[i].
That worked fine. It made possible to show 20-30 animated sprites on iPhone 4 (retina) at 40 fps.
That was enough for our needs.
Some performance hints:
- Use as less dynamically-created objects as possible.
- Use as less mouse-interacted objects as possible. Use mouseEnabled and mouseChildren to turn interaction off.
- Avoid moving large objects. Especially with alpha.
- Use cacheAsBitmap for everything is not animated and not rotated.
- Use cacheAsBitmapMatrix for everything else that is not animated, but need to be rotated or changed alpha.
- Don’t make plenty of ENTER_FRAME listeners. Make just one.
- Always count time in your ENTER_FRAME listener. So, if you’re moving an object by X pixels every frame, make a calculations on the elapsed time from the last listener call.
Retina vs lo-res.
How our application behave on different screen resolutions? It’s simple. It scales (but you make to change scene scale mode, of course).
That’s good for developing for iPhone 3/3GS and 4/4S. You just make a retina application and it automatically scales down on iPhone 3.
Of course, you can “read” the scene scale and show different graphics depending on what scale is it, but that seems to be quite tricky, so we left everything by default.
iPhone vs iPad.
Here is the same thing as with retina. Application scales. But in this case the scale factor will not be nice, so you need to make some custom code and custom graphics for iPad games.
That’s why we left our application iPhone-only. Maybe, we’ll make HD version for iPads some time later.
CPU vs GPU.
You can compile your Air application to use CPU or GPU for graphics. Using our graphic engine there was not great difference (it was about 10%).
But we’ve chosen CPU because when you compile under GPU you get some limitations. For example, effects don’t work. That mean that all text outlines and shadows wouldn’t be shown. The solution was to make an empty bitmap data object, draw a movie clip there and then put it on the stage. That works because when you use “draw” method, it uses software engine anyway and support of all effects presents.
But that also seemed very tricky and gave no advantage, so we left us at CPU mode.
Some other problems.
Adobe Air is a universal platform. That means that if you need to access some device-specific functionality like GameCenter, you need to install additional “native extensions”. That needs some tweaking building process, but after you find out what is what – everything is quite easy.
Also, the new versions of Air ignore the mute switch on the phone. So, we needed to use an extra native extension for that.
Also, we’ve developed all our game on PC. But on the last step we found out that we need a Mac anyway. The reason is that uploading an application to app store is only possible with an Application Loader software which is only available for Mac OS 10.6.8 and later.
To write on Flash Air or not to write? I think “yes”. To write.
Of course, there are some troubles and bottlenecks in performance. But Adobe is working on it and promises lots of improvements in near future. Speaking of dynamic games – that’s hard to make one that runs completely smooth on iPhone 4 with retina for now. But iPad 2 and iPhone 4S are much better.
So, we’re looking forward on Adobe and hope that Air will be a real platform for game development.
(c) 2012 GameJam