During the next stage of development I am going to focus down on designing the meat and potatoes of any game; the game logic. I think I've reached a point now with the other components that I have a fairly stable base from which to work from. The
Renderer is about 90% complete, the
UI component still needs some additional work, particularly the
GameScreen, and the sound interface is complete although I'll probably change some of the underlying code.
The game logic in most games contains some common components:
- The game class:- The interface to the game logic, keeps track of objects within the world, player score, level etc. Usually is responsible for updating and rendering these objects and handling game events.
- Game entities:- Objects in your world,, i.e. the player, enemies, sceneary etc.
- Physics:- The physical representation of your world, handles collision detection between game entities, determines what to do when objects collide, updates entities positions and orientations.
- Level:- It's sometimes desirable to have a class representing your level. These classes would handle level saving/loading, maintain checkpoints, render backgrounds, maybe contain a tile-system that can be used to colour your environment.
This is by no means an exhaustive list, but you get the idea. The game shouldn't know anything about the
Renderer,
UI or Sound components except for their interfaces.
True object-orientated design approaches for representing objects within the game world all-to-often fall flat. I've done it in the past with projects, you start out with a nice class
hierarchy all worked out then as you proceed with your design you begin to realise you're duplicating a lot of the functionality between cousin entities. So what do you do? Well, the traditional solution would be to propagate that functionality upwards until you reach the first common ancestor. I won't go into much detail but needless to say what you end up with is "one-for-all" classes (the "blob") which do a little bit of everything;
particularly OO friendly. In these designs usually the entity base class become vast and debugging a nightmare.
I'm somewhat of a proponent for component driven design. In composite designs containment is chosen over
inheritance. For example, rather than an object
inheriting the ability to explode on touch, it
contains the ability to explode on touch. The benefit of this design is that common code can easily be transported to various different entity types easily, without any need to propagating functionality up the
hierarchy or duplicate code. Basically each entity becomes a simple container for components and contain no functional code themselves, for a more detailed description I suggest you head
here.
This is the approach I'm hoping to use on
PhysTank. It's clean, easy to understand, easy to debug and allows additional functionality to be easily implemented. It is also receptive to a data-driven approach.
I'll probably start by creating the container class and the component interface.