Last month I made a game! More or less.
I made it as part of One Game a Month Dublin
, a group that loosely follows the format of One Game a Month
), where you have... wait for it... one month to make a game. I decided to do this has it's been ages since I've actually finished a game.
For the Dublin group there is an optional theme and then you get together at the end of the month to play each others games. There were a number of interesting games made this go around, including a dungeon explorer
, an intesting boss fight mini game [win32
], a stock trading card game and others.
For my own game I decided to ignore the theme of "Rogue" and instead have a go at adding gravity to my game engine and make a platformer.
That went in easily enough, although I had initially just added in the acceleration due to gravity and not the velocity it acted on (I've defined gravity as a separate 'force speed' that then modifies the overall object speed, basically using what I had already put in place for handling slopes
). This meant that at lower frame rates you couldn't jump as high, which i noticed when trying to play on my phone. Oops! Easily fixed.
I wanted to have the camera be a bit smoother, as it gets very jerky with all that jumping (although the jumping in the actual game is a bit smoother than portrayed in the videos), and I got some good suggestions from other members of the group on some simple code to make the camera lag behind the player.
camera.X -= (camera.X - player.X) / N;
//(the higher N the higher the slower it gets to the player)
I then went about creating background parallaxing, a new set of tiles, some basic character animations and added in some simple colour blocks and a block spawner. The aim of the game is simple enough; combine four similarly coloured blocks to create a bigger block. Then combine four of those bigger blocks to make an ever bigger block. The goal would be to get a large (level 3) block for each of the six colours, but each block has a limited lifetime (according to it's size) and there are also bombs to add in a bit of friction.
With a bit of extra work put into my object collision detection (it wasn't really up to handling multiple objects at once) and getting it to work on my Nexus 7 pretty smoothly I was more of less done for the month.
I actually like the game! I found that taking one minute to test a bug fix turned into ten minutes playing. So after the month was over I decided to keep on going and turn it into a finished game. This means I have to polish it up a bit; adding in the goal (which was missing), cleaning up the collision detection a bit (including stopping blocks from hanging in the air) and adding some character and animations to the blocks.
A bit of Polish and Tint
Following the universal law that all inanimate objects should have googly eyes, I created some simple animations for the blocks. To make things easier on myself I decided to make them greyscale and tint them at runtime. Trouble is if I do this the easy way with blanket tint using a colorTransform then it tints the eyes too, which I don't want. So I need to tint only selected pixels. Of course the obvious answer that immediately sprang to mind was to do exactly what Metaplace did (again!); alter the tintable pixels of a png so that (red-1) == green == blue
(where red==green==blue is greyscale), then at runtime check each pixel and if it matches those conditions then multiply by the tint colour. So I wrote a quick Paint.NET plugin to reduce red channel of selected pixels by one and then tested it in Flash. But I found that some pixels that should have been tinted weren't.
After much testing I discovered that the BitmapData of the png when it ends up in Flash is not the same as the data in the original file. Specifically for pixels that had some transparency the data could be off by one in one or all of the red, green and blue channels, which would screw up the very precise conditions of r-1==g==b. I spent a couple of days trying to get the exact data into flash by various means (ensuring no compression on Embed, using a loader, loading as a ByteArray, saving in different graphics program like gimp or even creating in php to ensure some png flag is set, pouring over the binary data with a hex editor etc.) to no avail. Something just happens to the data and I never found out what (I have a nagging feeling this is one of those areas where gaps in my self-taught knowledge are tripping me up, and someone could just say "Duh! Of course that happens, you didn't set your foo
to your bar
. Every n00b knows that!"). So I decided to see how Metaplace actually handled that by decompiling the client. Turns out I was being too restrictive with my r-1==g==b. From the looks of it maybe they ran into the same issue too; they had an allowable offset of 3 (although they went in the other direction). So changing my pngs to have an offset of 2 instead of 1 in the red channel and using the following appears to account for all cases...
if(green == blue && red < green && red > green - 4)
This would appear to allow the red to be off by one in either direction, while the original offset of two leaves the green and blue intact - or at least equal to each other - when embedded.
Of course the real power of this type of system is that it allows you to use three tinting colours, one for each colour channel, on a single image, which is overkill for this project but may end up being useful later down the line.
The game still needs a fair bit of work but I'll likely keep it very simple; simple goal, single map. I'll then put it up on FLG
and finish the android version. If it performs modestly well I might expand upon it. And I just might get to call myself a Game Developer again... maybe.
A not so up to date version can be played here