So How Does Halcyon Racer Work, on the code level?




           Halcyon Racer is actually quite simple from an organizational point of view. The number of main game classes is small; take a look at the class diagram. Below you will find a brief explanation of each class and an overview of which classes the game itself relies upon. Feel free to download the source code and take a look. The code is full of remarks and comments about what each function, class, etc is doing.




Base classes


Classes borrowed

COpenGLControlBase, COpenGLManager – Provide MFC wrapper for OpenGL drawing
IV Parser – Loads in Inventor models (.iv) and converts them into an OpenGL display list
C3Dmodel – class wrapper for drawing and loading inventor models
COpenGLImage – class for dealing with loading images and converting them to textures
CDSList, CDSBuffer – classes for dealing with DirectSound

Classes written

CGameEngine – inherits from COpenGLControlBase
                      Sets up state machine for what to update and draw in which part of the game
C3Dmodel – class wrapper for drawing and loading inventor models



Object hierarchy


CEnvironment - Container class for game world
CTrack – class for drawing the track and checking for collision with the track
CCar - Base class for all cars
CUserCar - Adds user interface to CCar
CEnemyCar - Adds enemy AI to CCar




So how do these make a game?


CGameEngine

          CGameEngine intercepts all the messages it needs through MFC. Then, it distributes the needed messages throughout the object hierarchy (when needed) to affect the running game. This is done by using member functions set up in CEnvironment. CEnvironment than decides from those messages, what to send to CUserCar, CEnemyCar (each enemy car actually, there are multiple ones), and to the CTrack. CGameEngine also handles all of the introduction screens (the spinning car at the beginning and the menu, etc) and all sound playing.


CCar

          CCar is where everything about driving takes place. All the cars move, speed up, slow down, skid, run into walls, etc. according to this class. Physics are implemented here that take care of momentum and collision detection as well. Since all cars (the user car and all enemy cars) inherit from this class, all cars drive following the same rules. CUserCar inherits from this and adds a method to get user input and translate that into movements of the car. It also prints out feedback information to the user. CEnemyCar, conversely, adds artificial intelligence methods instead of user input.