Putting Together a Full Game(8)
Structuring the Application
The main application is relatively small (if you can call just under 1,500 lines of
code small). It has the job of initializing all the required components and tracking
the game state (that’s right, state-based processing is even used here).
First, you declare the application class. Although the class is incomplete at this
point, throughout the rest of this chapter, the pieces fall into place, and the application
class becomes complete. Now, check out the sections of the application class
that set up the class data and initialize the game system:
#include "core_manager.h"
#include "core_graphics.h"
#include "core_framework.h"
#include "core_input.h"
#include "core_sound.h"
#include "text_window.h"
#include "spell_controller.h"
#include "trigger.h"
#include "barrier.h"
#include "game_chars.h"
#include "game_script.h"
#define SOUND_CHAR_ATTACK 0
#define SOUND_MONSTER_ATTACK 1
#define SOUND_FIREBALL 2
#define SOUND_ICE 3
#define SOUND_HEAL 4
#define SOUND_TELEPORT 5
#define SOUND_GROUNDBALL 6
#define SOUND_CONCUSSION 7
#define SOUND_EVIL_FORCE 8
#define SOUND_ROAR 9
#define SOUND_CHAR_HURT 10
#define SOUND_MONSTER_HURT 11
#define SOUND_CHAR_DIE 12
#define SOUND_MONSTER_DIE 13
#define SOUND_BEEP 14
#define SPELL_FIREBALL 0
#define SPELL_ICE 1
#define SPELL_HEAL 2
#define SPELL_TELEPORT 3
#define SPELL_GROUNDBALL 4
#define SPELL_CONCUSSION 5
#define SPELL_EVIL_FORCE 6
#define ID_PLAYER 0
class cApp;
class cGameSpells : public cSpellController
{
private :
cApp* m_app;
public :
void attach_app(cApp* app) { m_app = app; }
virtual void play_spell_sound( long index);
};
/************************************************************************************************/
class cApp : public cFramework
{
friend class cGameScript;
friend class cGameChars;
friend class cGameSpells;
friend void menu_frame( void * data, long purpose);
friend void game_frame( void * data, long purpose);
friend void status_frame( void * data, long purpose);
friend void barter_frame( void * data, long purpose);
////////////////////////////////////////////////////////////////////////////////////////// /
private :
ID3DXFont* m_font;
IDirect3DTexture9* m_scene_backdrops[6];
IDirect3DTexture9* m_charge_bar;
long m_scene_index;
cCamera m_camera;
cInput m_input;
cInputDevice m_keyboard;
cInputDevice m_mouse;
cSound m_sound;
cSoundChannel m_sound_channel;
cMusicChannel m_music_channel;
cSoundData m_sound_data;
cMesh m_scene_mesh;
cObject m_scene_object;
cGameChars m_game_chars;
cGameSpells m_game_spells;
cTextWindow m_text_stats;
cTextWindow m_text_window;
cTextWindow m_text_header;
cGameScript m_game_script;
long m_teleport_map; // map to teleport on next frame (-1 = none)
bool m_is_monster_last_frame; // flag if monsters during last frame
long m_combat_exp; // combat booty to reward at end of combat
long m_combat_money;
cTrigger m_trigger;
cBarrier m_barrier;
sItem m_mil[1024]; // the master item list
cManager m_state_manager;
////////////////////////////////////////////////////////////////////////////////////////// /
public :
cApp()
{
m_font = NULL;
m_charge_bar = NULL;
m_scene_index = 0;
m_combat_exp = 0;
m_combat_money = 0;
m_teleport_map = -1;
m_is_monster_last_frame = false ;
ZeroMemory(m_scene_backdrops, sizeof (m_scene_backdrops));
ZeroMemory(m_mil, sizeof (m_mil));
}
virtual bool init();
virtual void shutdown();
virtual bool frame();
////////////////////////////////////////////////////////////////////////////////////////// /
private :
float get_height_below( float x_pos, float y_pos, float z_pos);
bool check_intersect( float x_start, float y_start, float z_start,
float x_end, float y_end, float z_end,
float * dist);
void render_frame( long elapsed);
void free_level();
bool load_level( int scene_index);
void play_sound( long index);
void play_music( long index);
void stop_music();
void win_game();
void start_of_combat();
void end_of_combat();
void teleport_player( long map, float x_pos, float y_pos, float z_pos);
void setup_barter( const char * ics_file);
sCharacter* get_char_at( long mouse_x_pos, long mouse_y_pos);
bool last_point_reached(sCharacter* character);
};
The application class begins by setting three friend class references. Those three
classes, cGameSpells, cGameChars, and cGameScript, are the derived controllers for the spells,
characters, and scripts, respectively. Each of those classes need special access to
the application class, so you can make them friends.
The next portion of the cApp class declares a list of Game Core specific
objects, all of which are private to the cApp class.
From the Graphics Core, you can see the use of the graphics, font, and camera
objects. For input, there’s the input system object, plus a device for each the keyboard
and mouse. Rounding off the lot are objects for using the sound system, a
single sound and music channel, and a sound data object for loading sounds.
A small bitmap stores the graphics used to display the player’s charge bar (the
amount of charge built up for attacking). You store this bitmap using a texture
object. Following that, you include three text window objects to display various
dialogue and screen text.
At this point in the application class declaration, you define a couple of miscellaneous
private functions.
The win_game function is called whenever a script encounters the win-game action.
This action triggers the end of game, which returns play back to the main menu.
get_char_at is the function that determines which character a user clicks with the mouse.
Completing cApp are the class constructor and the overridden init, shutdown, and
frame functions, all of which you declare with public accessibility.