下载源码和工程
增加的关键代码以红色标示:
#define MAX_PLAY_SOUND 4
#define SOUND_ATTACK 0
#define SOUND_FIRE 1
#define SOUND_GROUNDBALL 2
#define SOUND_ICE 3
class cApp : public cFramework
{
friend class cGameScript;
friend class cGameCharController;
private:
cCamera m_camera;
cInput m_input;
cInputDevice m_keyboard;
cInputDevice m_mouse;
cMesh m_terrain_mesh;
cObject m_terrain_object;
cGameCharController m_gc_controller;
cSpellController m_spell_controller;
cGameScript m_game_script;
sItem m_mil[1024];
ID3DXFont* m_font;
cSound m_sound;
cSoundData m_sound_data[MAX_PLAY_SOUND];
cSoundChannel m_sound_channel[MAX_PLAY_SOUND];
public:
bool init();
bool frame();
long get_input();
bool check_intersect(float x_start, float y_start, float z_start,
float x_end, float y_end, float z_end);
public:
void play_attack()
{
if(!m_sound_channel[SOUND_ATTACK].is_playing())
m_sound_channel[SOUND_ATTACK].play(&m_sound_data[SOUND_ATTACK], 100, 1);
}
void play_fire()
{
if(!m_sound_channel[SOUND_FIRE].is_playing())
m_sound_channel[SOUND_FIRE].play(&m_sound_data[SOUND_FIRE], 100, 1);
}
void play_groundball()
{
if(!m_sound_channel[SOUND_GROUNDBALL].is_playing())
m_sound_channel[SOUND_GROUNDBALL].play(&m_sound_data[SOUND_GROUNDBALL], 100, 1);
}
void play_ice()
{
if(!m_sound_channel[SOUND_ICE].is_playing())
m_sound_channel[SOUND_ICE].play(&m_sound_data[SOUND_ICE], 100, 1);
}
};
/*************************************************************************************************/
bool cApp::init()
{
create_display(g_hwnd, CLIENT_WIDTH, CLIENT_HEIGHT, 16, true, true);
set_perspective(D3DX_PI/4, 1.3333f, 1.0f, 10000.0f);
create_font(&m_font, "Arial", 16, true, false);
m_input.create(g_hwnd, get_window_inst());
m_keyboard.create_keyboard(&m_input);
m_mouse.create_mouse(&m_input, true);
m_sound.init(g_hwnd, 22050, 1, 16, DSSCL_PRIORITY);
m_sound_data[SOUND_ATTACK].load_wav("..\\data\\attack.wav");
m_sound_data[SOUND_FIRE].load_wav("..\\data\\fire.wav");
m_sound_data[SOUND_GROUNDBALL].load_wav("..\\data\\groundball.wav");
m_sound_data[SOUND_ICE].load_wav("..\\data\\ice.wav");
for(int i = 0; i < MAX_PLAY_SOUND; i++)
{
m_sound_channel[i].create(&m_sound,
m_sound_data[i].get_frequency(),
m_sound_data[i].get_channels(),
m_sound_data[i].get_bits_per_sample());
}
m_terrain_mesh.load("..\\Data\\World.x", "..\\Data\\");
m_terrain_object.create(&m_terrain_mesh);
// load the master item list
ZeroMemory(m_mil, sizeof(m_mil));
FILE* fp;
if((fp = fopen("..\\Data\\Default.mil", "rb")) == NULL)
return false;
fread(m_mil, 1, sizeof(m_mil), fp);
fclose(fp);
m_spell_controller.init("..\\Data\\Default.msl",
array_num(g_spell_mesh_names), g_spell_mesh_names,
"..\\Data\\");
m_gc_controller.init(m_font, "..\\Data\\Default.mcl",
m_mil, m_spell_controller.get_spell_list(),
array_num(g_char_mesh_names), g_char_mesh_names,
"..\\Data\\", "..\\Data\\",
array_num(g_char_anim_infos), g_char_anim_infos);
m_spell_controller.attach(&m_gc_controller);
m_gc_controller.attach(&m_spell_controller);
m_gc_controller.set_data(this);
// add the character player
m_gc_controller.add_char(0, 0, CHAR_PC, CHAR_STAND, 0.0f, 0.0f, 0.0f, 3.14f);
// process the startup script
m_game_script.set_data(this, &m_keyboard, &m_gc_controller, m_font);
m_game_script.execute("..\\Data\\Startup.mls");
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
bool cApp::frame()
{
static DWORD update_counter = timeGetTime();
// lock to 30fps
if(timeGetTime() < update_counter + 33)
return true;
update_counter = timeGetTime();
m_keyboard.acquire();
m_keyboard.read();
// exit if ESC pressed
if(m_keyboard.get_key_state(KEY_ESC))
return false;
m_gc_controller.update(33);
m_spell_controller.update(33);
m_camera.point(0.0f, 700.0f, -700.0f, 0.0f, 0.0f, 0.0f);
set_display_camera(&m_camera);
clear_display(0, 1.0f);
if(begin_display_scene())
{
enable_zbuffer();
m_terrain_object.render();
m_gc_controller.render(-1, NULL, 0);
m_spell_controller.render(NULL, 0);
static sCharacter* character = m_gc_controller.get_char(0);
char stats[128];
sprintf(stats, "HP: %ld / %ld\r\nMP: %ld / %ld",
character->health_points, character->char_def.health_points,
character->mana_points, character->char_def.mana_points);
draw_font(m_font, stats, 2, 2, 0, 0, COLOR_WHITE, DT_LEFT);
end_display_scene();
}
present_display();
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
long cApp::get_input()
{
long action = 0;
if(m_keyboard.get_key_state(KEY_UP) || m_keyboard.get_key_state(KEY_W))
action |= PRESS_UP;
if(m_keyboard.get_key_state(KEY_RIGHT) || m_keyboard.get_key_state(KEY_D))
action |= PRESS_RIGHT;
if(m_keyboard.get_key_state(KEY_DOWN) || m_keyboard.get_key_state(KEY_S))
action |= PRESS_DOWN;
if(m_keyboard.get_key_state(KEY_LEFT) || m_keyboard.get_key_state(KEY_A))
action |= PRESS_LEFT;
if(m_keyboard.get_key_state(KEY_SPACE))
{
action |= PRESS_SPACE;
m_keyboard.m_locks[KEY_SPACE] = true;
m_keyboard.set_key_state(KEY_SPACE, false);
}
if(m_keyboard.get_key_state(KEY_1))
{
action |= PRESS_1;
m_keyboard.m_locks[KEY_1] = true;
m_keyboard.set_key_state(KEY_1, false);
}
if(m_keyboard.get_key_state(KEY_2))
{
action |= PRESS_2;
m_keyboard.m_locks[KEY_2] = true;
m_keyboard.set_key_state(KEY_2, false);
}
if(m_keyboard.get_key_state(KEY_3))
{
action |= PRESS_3;
m_keyboard.m_locks[KEY_3] = true;
m_keyboard.set_key_state(KEY_3, false);
}
return action;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
bool cApp::check_intersect(float x_start, float y_start, float z_start,
float x_end, float y_end, float z_end)
{
for(sMeshInfo* mesh_info = m_terrain_mesh.get_root_mesh(); mesh_info != NULL; mesh_info = mesh_info->m_next)
{
if(is_ray_intersect_mesh(mesh_info->m_d3d_mesh, x_start, y_start, z_start, x_end, y_end, z_end, NULL))
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////
void cGameCharController::play_action_sound(sCharacter* character)
{
if(character->action == CHAR_ATTACK)
m_app->play_attack();
if(character->action == CHAR_SPELL && character->spell_index == SPELL_FIRE)
m_app->play_fire();
if(character->action == CHAR_SPELL && character->spell_index == SPELL_GROUNDBALL)
m_app->play_groundball();
if(character->action == CHAR_SPELL && character->spell_index == SPELL_ICE)
m_app->play_ice();
}