Monday, 28 February 2011
Friday, 25 February 2011
Tuesday, 22 February 2011
- The game can't have more than 1 level that you need to design. So a single maze like Pacman would be ok, but you can't have every level be different.
- You can't require any complex artwork. You need to use either free art, cheap stock art, art you already have kicking around, or art you can put together in 1 or 2 hours.
- You need a game engine to start off with. Flixel and Flashpunk might work for you, but I prefer to use my own engine, which I have been revising and improving for well over a year. It's still nowhere near "finished", but I'm not writing much low-level code for each new game.
- You need a template .fla and/or FlashDevelop template already set up so you don't have to write any boilerplate for Mochi-ads, screen management, preloading etc
- Your game must have a way of automatically progressing - with either randomly generated levels, or a simple way of getting progressively harder automatically. Players expect to go on a journey of increasing peril, but that's hard to "author" in just a few hours, so automating it is the only way to go.
- Your game can't introduce you to any programming techniques that you've never done before - e.g. new type of collision detection. Learning a new technique is a fine way to spend an afternoon, just don't expect a game at the end of it.
- The game must have reasonably similar gameplay to an existing game, so you're not working every aspect of game design out from scratch. If you add even one or two elements to a game that are completely novel, you've done more than most. Combining game mechanics from different games that you enjoy seems like a logical starting point.
- Don't try to make all the code you write reusable - just get the game done, you can always come and copy bits out of it later.
- Don't throw your idea out half-way. Once you come up with your idea and started coding, you might as stick with it and do the best job you can to make it fun. Even if it doesn't turn out to be the new Tetris, at least you will have another completed game under your belt.
Thursday, 17 February 2011
Over on Richard “PhotonStorm” Davey’s blog he proposed a simple way to communicate between objects in your game using a “Registry” a class with static variables storing all the major systems of your game. So, for example if you wanted to create a spray of blood when an enemy is hit, in the enemy’s hit() function you would include the line Registry.fx.sprayBlood(x, y) and the FX object stored in the Registry.fx variable would create the blood spray and handle updating etc.
In the comments on Richard’s post, I pointed out that this isn’t a very object-oriented approach: these are basically global variables by a different name. I have used a similar approach myself on quite a few games projects, and overall it works well and is a quick way of getting things done. I have, however, encountered two problems with it.
Firstly, you can end up with all you code in one huge blob or “god class”. For example, if the FX class is responsible for handling any possible visual effect you would want to create, it could end up getting very big. But, other than academic notions of “good” and “bad” code, there’s nothing especially wrong with having big classes. They may be a bit harder to maintain and reuse, but nothing to worry about too much.
Secondly, using static/global variables as a communication method means you can be limited to having only one “game” in a single project. Now in most scenarios this wouldn’t be a problem, but it’s normally best not to assume you will only ever have one of a particular class of object. I’ve worked on several Flash projects that were collections of minigames in a single swf. Where I was relying on static variables in some of my base-classes and utility classes, I started to see clashes between the different games.
Ok so how do I handle the same problems? Well, say an enemy needs a reference to the player in order to chase after them. Rather than looking up Registry.player, I would just have a “player” variable in my enemy class and I would pass in the value of player when I create the enemy, or once I know the player exists. Or if the enemy needed more than a couple of different references from game in order to work, I would just pass in a reference to the game itself, and let the object access whatever information it needs. As Richard points out, the downside to this approach is that you end up with a lot of references in different places. This isn’t really a problem if you null your references when destroying objects, but it is more work, and you can leak memory if you’re sloppy with it.
Secondly, pretty much everything in my game extends a base Entity class. I have a main Game class that manages all these entities. Game has a method called addEntity(entity:Entity) which adds any new entities I create to the array of entities. Every frame I loop through all my entities and call their public update() function (to pause the game, I just don’t run this loop).
So say I have a SpaceShip object that creates a Bullet object every time it fires. How would I let the game know? I wouldn’t call Game.instance.addEntity() because I may have more than one mini-game that extends my base Game class in a single project. Instead, the base Entity class has a function addEntity(entity:Entity) which dispatches an AS3Signal with the entity value. My game is listening for this signal, and directs the entity to its own addEntity function. You could also use an event to achieve the same effect. Now any Entity can itself create more entities and add them to the game.
How would I use this to solve the problem of creating a spray of blood? I would create two Entity classes. One class is BloodDrop which is a single particle of blood. Every update() it moves based on its speed and falls with gravity, and after 30 frames it fades out and destroys itself. The other class is BloodSpray, which lives for a single frame, and in that frame just runs a loop creating 100 instances of BloodDrop, setting their initial position and speed, and calling addEntity(bloodDrop). Now to add my spray of blood in the enemy’s hit() function, I simply create a new BloodSpray, set its position to match the enemies position and call addEntity(bloodSpray). All the entities know how to update and destroy themselves and are pooled for reuse.
This won’t solve all the communication problems in your game, but it will solve a big chunk of them, and now your code is neatly organised into distinct Entity classes which each perform a single purpose.
Happy coding! I think my next conference/user group talk might have to be one about organising game code :)