If you live in a cave you might have missed the ultra hard mobile game Flappy Bird that went viral recently. I wanted to build a proof of concept prototype version of Flappy Bird using Delphi XE5 Firemonkey and this is what I came up with. The game is called Flappy Firemonkey and I built it in a few hours. The code is very rough and it could use a lot of optimization and polish but it’s playable. It works best on Windows and I also tested it on Android and IOS but not OSX. It uses a TMemIniFile to save your best score, rudimentary collision detection, a game loop, opening a cross platform URL, and does some things with TFloatAnimation as well. Handling all of the different screen sizes was harder than I thought but I have run out of time for handling more screen sizes than a normal Android device and the Google Nexus 4 size device on Windows.
Things that worked out well:
- I accomplished the animation of the firemonkey and the moving ground bar by just using two frames and doing TBitmap.Assign() between them which is not at all the best way to do it but it works for a prototype. For a production project I would probably switch to this TSprite component or try to get TBitmapListAnimation working.
- Using a TTimer for the game loop worked out well. It keeps the game rendering separate (hopefully). I might try using a Firemonkey 3D form (see below) because it has an OnRender event.
- Using ShowModal on Windows and just Show on mobile worked as I had hoped. Adding in Hide to the Menu Form when the Game Form is active also worked like I wanted.
- I based my collision detection off of some code I found on Torry’s. The collision detection was one of the last things I added. There are a couple other methods to do collision detection like IntersectRect() and TRect.Intersect (and probably more). I would have to test each method to see which ones are the fastest for mobile.
- Building the pipes out of TRectangle worked but I ended up moving them into a TLayout to make the collision detection work correctly.
- I combined this code and this code for the open URL functionality.
- The cross platform functionality is awesome. I built and tested it with the Win32 target and switching the target to compile to Android and it just worked.
Things that did not work out so well:
- I attempted to apply a ratio to my hard coded movement and placement numbers so that it would take the screen size into account but was unable to really get or make a usable ratio for the screen size.
- I had some more Delphi XE5 Firemonkey effects like bevel and glow on my Game Over screen that I was using but once I started testing on mobile I had to remove them to get a better framerate.
- Originally I parented all of the objects on the Game Over screen off a TLabel but that fell apart once I started testing on multiple resolutions. I ended up switching to a TLayout and putting all of the Game Over objects in there.
- I had a TFloatAnimation on the Game Over screen but once I moved to the TLayout for multiple resolutions it no longer functioned how I had built it so I ended up disabling it.
- Moving the pipes manually seems slow and I would want to see if using a TFloatAnimation on them might be faster.
- Using TRectangles for the pipe may not have been the best choice for mobile optimization. I think I would try switching it to a TImage for mobile optimization.
- Some of the graphics (like the background) are included in the application twice because it made for easy visual editing. A simple fix would be to have one graphic and Assign() the other versions of it at runtime. I might also try to use Frames to do this but I’m not sure how they do transparency.
- Using a visually designed TBitmapAnimation to swap between the images of the flying firemonkey and the ground bar didn’t really work out. I think it is more for a longer transition than 33 ms.
- I didn’t have a really good and easy way to handle the background on multiple screen sizes without doing a lot of extra lifting. I settled for making a big background image set to center and setting the background form color to the same color as the sky. More testing on multiple resolutions would show how well this worked. I guess the multiresolution functionality in TImage might help with this.
- I was not able to achieve a really solid outline around text using the glow effect component.
- I had a plan to set the position of the second window (GameForm) to the same X and Y as the Menu Form (so they would be right above each other on Windows) but I didn’t find an easy way to make that happen.
- I wanted to have a TStyleBook on the form for each OS and then use an IFDEF to set the premium Diamond style at runtime. This did not work out.
Update: I created a second version that uses a Firemonkey 3D form and a Layer3D. It is still 2D but rendered on the 3D layer. Seems faster.
Update 2: Developer Croco Tronic updated my original version of the source and implemented a thread for the game loop in addition to a lot of other code optimizations.
Here is a custom themed version on Google Play called Aswang – Manananggal Edition.
Update 3 (4/4/2014): Developer Croco Tronic and I both put new code into his version which fixes some bugs with it.
You can download the updated version here: Delphi XE5 Firemonkey Flappy Bird Clone.
Update 4 (5/16/2014): New XE6 compatible versions available: