Wednesday, March 4, 2009

The Game Loop

So here is a quick rundown of how a game might work. I guess at times I refer to a game skeleton or a 'game loop' - this is what I am referring to. The cycle that happens over and over again during a game's execution (often every frame!), and the things that need to be done in that cycle. It is obviously essential for programmers to understand this since they have to code it (or something like it), but I think it is important for everyone working on a games project to at least have an appreciation of just what is happening under the hood.

In the most basic of descriptions it would be:

  1. initialise resources (screen, images/textures/sounds)
  2. initialise game state (score, lives, all the entities (enemies, player, etc) )
  3. while not ready to exit:
  4. ....get input (keyboard/mouse)
  5. ....test for collisions between entities
  6. ....update all the entities positions/state
  7. ....draw everything
  8. clean up

Thats about it. Obviously some of the input (say, ESC key) or some game state (player ran out of lives) might cause the 'ready to exit' case to be true, and the game would end. You also need to fill in the blanks a bit with the 'test for collisions' step - obviously you arent interested in every little collision - just the ones that affect game state. Normally these are things like player/enemy, player/enemy_bullet, player/powerup. This generally means separating entities into groups, and testing for collisions between the groups that make sense - pygame has some neat data structures for this.

Another thing I am not really touching on here is timing. Some games (admittedly, these days it is not many) are written without any thought to how long each cycle (the part in the while loop - input, processing, and output/render). They just go as fast as they can. The problem with this is that people playing the game on different systems with different run speeds will have completely different play experiences. This is not desirable - it really undermines your game design. So what you have to do in these situations is have a clock timing how long it is taking to render each frame (the so called dt - normally in milliseconds), and do everything based on that.

For instance, instead of moving the spaceship 3 pixels every cycle or frame (which would have the ship moving at *vastly* different rates on different systems), we instead say that the ship moves at 100 pixels per second, so that each frame the ship moves (100*(dt/1000)) pixels. This means the ship moves at the same rate (more or less) on every system you run it on.

It sounds complex, but it's not.

The other nifty thing we will be doing comes when we want to 'update' all our entities. Essentially what we will do is make a base class in python for entities that has some useful methods, among them update() and draw(). Whenever we define a new type of entity (a bullet, a monster, a powerup, a zombie dinosaur), we will subclass from here (i.e. inherit from here) and override the functionality of update() and draw() to suit whatever entity we happen to be working on. The beauty of this is that we end up having our entities in some sort of list or group, and when we are ready to update or draw them, we just call entity.update() or entity.draw() on each element of the list, and each element then runs its custom update() method, depending on what it is. Inheritance comes in quite handy for games.

So our (slightly more advanced) game loop might be:

  1. init resources (screen, images/textures/sounds)
  2. init a clock
  3. init game state
  4. groups entities for collisions
  5. while not ready to exit:
  6. ....tick the clock (gets the time taken since last tick) to get 'dt'
  7. ....get input (keyboard/mouse)
  8. ....go through and test for collisions between groups we are interested in
  9. ....go through each element in the element lists and call .update() based on 'dt'
  10. ....go through each element in the element lists and call .draw()
  11. clean up


Next step: How will we do this in python/pygame? Stay tuned!

No comments:

Post a Comment