下载源码和工程
![](http://www.cppblog.com/images/cppblog_com/lovedday/5498/o_char_first_sight.jpg)
修改的关键代码以红色标示:
/*
0
^
|
|
|
4.71----------------------------------------> 1.57
|
|
|
|
3.14
*/
const float g_angles[13] =
{
0.0f,
0.0f, 1.57f, 0.785f, 3.14f,
0.0f, 2.355f, 0.0f, 4.71f,
5.495f, 0.0f, 0.0f, 3.925f
};
void cGameCharController::pc_update(sCharacter* character, long elapsed,
float* x_move, float* y_move, float* z_move)
{
if(character->id != CHAR_PC)
return;
float speed = elapsed/500.0f * get_speed(character);
long m_action = m_app->get_input();
cCamera* camera = m_app->get_camera();
static float move_angle = 0.0f;
if((m_action & PRESS_UP) || (m_action & PRESS_RIGHT) || (m_action & PRESS_DOWN) || (m_action & PRESS_LEFT))
{
move_angle = g_angles[m_action] + camera->m_y_rot; // key diretion + mouse direction
*x_move = sin(move_angle) * speed;
*z_move = cos(move_angle) * speed;
character->direction = move_angle;
character->action = CHAR_MOVE;
}
sCharacter* char_ptr;
float x_diff, y_diff, z_diff, dist;
// attack a nearby monster or process NPC script
if(m_action & PRESS_SPACE)
{
for(char_ptr = get_root_char(); char_ptr != NULL; char_ptr = char_ptr->next)
{
// only check other characters
if(char_ptr->id == character->id)
continue;
x_diff = fabs(char_ptr->pos_x - character->pos_x);
y_diff = fabs(char_ptr->pos_y - character->pos_y);
z_diff = fabs(char_ptr->pos_z - character->pos_z);
dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;
// only check characters within 1000.0 units distance
if(dist > 10000.0f)
continue;
if(char_ptr->script_filename[0])
m_app->m_game_script.execute(char_ptr->script_filename);
else
{
// turn toward victim
x_diff = char_ptr->pos_x - character->pos_x;
z_diff = char_ptr->pos_z - character->pos_z;
character->direction = atan2(x_diff, z_diff);
character->victim = char_ptr;
char_ptr->attacker = character;
m_app->m_gc_controller.set_char_action(character, CHAR_ATTACK, 0);
}
break;
}
}
long spell_index = SPELL_FIRE;
// cast spells
if(m_action & PRESS_1 || m_action & PRESS_2 || m_action & PRESS_3)
{
// get spell index to cast
if(m_action & PRESS_1) spell_index = SPELL_FIRE;
if(m_action & PRESS_2) spell_index = SPELL_GROUNDBALL;
if(m_action & PRESS_3) spell_index = SPELL_ICE;
float spell_max_dist = m_app->m_spell_controller.get_spell(spell_index)->max_dist;
// search for closest monster
for(char_ptr = get_root_char(); char_ptr != NULL; char_ptr = char_ptr->next)
{
if(char_ptr->type == CHAR_MONSTER)
{
x_diff = fabs(char_ptr->pos_x - character->pos_x);
y_diff = fabs(char_ptr->pos_y - character->pos_y);
z_diff = fabs(char_ptr->pos_z - character->pos_z);
dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;
if(dist <= (spell_max_dist * spell_max_dist))
{
character->spell_index = spell_index;
character->target_type = CHAR_MONSTER;
character->target_x = char_ptr->pos_x;
character->target_y = char_ptr->pos_y;
character->target_z = char_ptr->pos_z;
// turn toward victim
x_diff = char_ptr->pos_x - character->pos_x;
z_diff = char_ptr->pos_z - character->pos_z;
character->direction = atan2(x_diff, z_diff);
m_app->m_gc_controller.set_char_action(character, CHAR_SPELL, 0);
break;
}
}
}
}
}
bool cApp::frame()
{
static DWORD update_counter = timeGetTime();
// lock to 30fps
if(timeGetTime() < update_counter + 33)
return true;
DWORD elapsed = timeGetTime() - update_counter;
update_counter = timeGetTime();
m_keyboard.acquire();
m_keyboard.read();
m_mouse.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);
static sCharacter* character = m_gc_controller.get_char(CHAR_PC);
static float cam_angle = 0.0f;
cam_angle -= ((float)m_mouse.get_x_delta() * elapsed / 800.0f);
m_camera.point(character->pos_x + cos(cam_angle) * 300.0f,
character->pos_y + 100.0f,
character->pos_z + sin(cam_angle) * 300.0f,
character->pos_x, 0.0f, character->pos_z);
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);
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;
}