📄 player.cpp
字号:
/********************************************************************
created: 2004/05/25
created: 25:5:2004 15:07
filename: d:\Works\Gamelib\Player.cpp
file path: d:\Works\Gamelib
file base: Player
file ext: cpp
author: lazybug
purpose: CPlayer类得实现部分
*********************************************************************/
#include "stdafx.h"
#include "GameObj.h"
#include "callback_functions.h"
#include "Gamelogic.h"
#include <cmath>
#include <mmsystem.h>
#define PI 3.1415926
using namespace std ;
CPlayer::CPlayer(const string& name)
{
// 打开相应人物的profile读取执行
fstream in ;
string filename = ".\\Actor\\" ;
SPropertyItem item ;
GameRes* res_info ;
string script ;
string small_res_name ;
string middle_res_name ;
string big_res_name ;
string face_res_name ;
// 人物属性还没有图片
item.icon_id = -1 ;
filename += name ;
filename += ".profile" ;
in.open(filename.c_str(), ios::in) ;
if ( in.is_open() )
{
// 人物说明,可以带有tag标记
in >> self_description ;
// 读人物的四个图片资源名:小,中,大,头像
in >> small_res_name >> middle_res_name >> big_res_name >> face_res_name ;
// 读入人物属性
in >> item.name >> item.val ;
while ( item.name != "END" )
{
m_property.push_back( item ) ;
in >> item.name >> item.val ;
}
// 读入人物技能
in >> item.name >> item.description >> item.val ;
while ( item.name != "END" )
{
m_skills.push_back( item ) ;
in >> item.name >> item.description >> item.val ;
}
// 读入人物说话列表
in >> script ;
while ( script != "END" )
{
this->push_script( script ) ;
in >> script ;
}
// 读入人物说话方式
in >> script ;
if ( script == "RANDOM" )
{
SetTalkState( CPlayer::RANDOM ) ;
}
else if ( script == "CONDITIONAL" )
{
SetTalkState( CPlayer::CONDITIONAL ) ;
}
else if ( script == "LOOP" )
{
SetTalkState( CPlayer::LOOP ) ;
}
else if ( script == "CONTINUAL" )
{
SetTalkState( CPlayer::CONTINUAL ) ;
}
else
{
string reason = "Unexpected npc talk style '" ;
reason += script ;
reason += "' when reading profile :";
reason += filename ;
throw logic_error( reason.c_str() ) ;
}
}
/*
* 根据人物profile提供的信息向Unicough引擎申请图片资源
*/
if ( small_res_name != "NULL" )
{
res_info = context->GetRes(small_res_name) ;
(*LoadActor)( res_info->filename.c_str(), res_info->h_frame, res_info->v_frame, res_info->color_key, &Small_Res_id ) ;
this->ResID = Small_Res_id ;
}
if ( middle_res_name != "NULL" )
{
res_info = context->GetRes(middle_res_name) ;
LoadActor( res_info->filename.c_str(), res_info->h_frame, res_info->v_frame, res_info->color_key, &Middle_Res_id ) ;
this->ResID = Middle_Res_id ;
}
if ( big_res_name != "NULL" )
{
res_info = context->GetRes(big_res_name) ;
LoadActor( res_info->filename.c_str(), res_info->h_frame, res_info->v_frame, res_info->color_key, &Big_Res_id ) ;
this->ResID = Big_Res_id ;
}
if ( face_res_name != "NULL")
{
res_info = context->GetRes(face_res_name) ;
LoadActor( res_info->filename.c_str(), res_info->h_frame, res_info->v_frame, res_info->color_key, &face_Res_id ) ;
}
this->name = name ;
this->x = 0 ;
this->y = 0 ;
this->facing = 0 ;
this->attack_str = NULL ;
this->active_in_scene = false ;
this->is_doing_task = false ;
this->is_loop = false ;
this->waiting_mode = false ;
this->is_dead = false ;
this->is_auto_attack = false ;
this->state = CGameLogic::STOP ;
this->m_current_words = 0 ;
}
CPlayer::~CPlayer()
{
}
SPropertyItem* CPlayer::Property(const std::string& name)
{
vector<SPropertyItem>::iterator pos = m_property.begin() ;
for ( ; pos != m_property.end(); pos++ )
{
if ( pos->name == name )
{
return &(*pos) ;
}
}
throw exception("try to get nonexsisted player property!") ;
}
SPropertyItem* CPlayer::Skill(const std::string& name)
{
vector<SPropertyItem>::iterator pos = m_skills.begin() ;
for ( ; pos != m_skills.end(); pos++ )
{
if ( pos->description == name )
{
return &(*pos) ;
}
}
string what = "try to get nonexsisted player skill: " ;
what += name ;
throw exception( what.c_str() ) ;
}
SPropertyItem* CPlayer::FindTools(const std::string& description)
{
vector<SPropertyItem>::iterator pos = m_tools.begin() ;
for ( ; pos != m_tools.end(); pos++ )
{
if ( pos->description == description )
{
return &(*pos) ;
}
}
return NULL ;
}
void CPlayer::DelTools(const std::string& description)
{
vector<SPropertyItem>::iterator pos = m_tools.begin() ;
for ( ; pos != m_tools.end(); pos++ )
{
if ( pos->description == description )
{
m_tools.erase( pos ) ;
return ;
}
}
}
void CPlayer::AddTool(SPropertyItem& tool )
{
m_tools.push_back(tool) ;
}
void CPlayer::SetActiveRes(RanderState s )
{
switch (s)
{
case BIG :
this->ResID = Big_Res_id ;
break;
case SMALL :
this->ResID = Small_Res_id ;
break;
case MID:
this->ResID = Middle_Res_id ;
break ;
default:
throw logic_error("Unexpected rander state when CPlayer::SetActiveRes()") ;
}
}
/*
* 清空所有任务路点
*/
void CPlayer::flush_all_way_point()
{
m_way_points.clear() ;
is_doing_task = false ;
}
/*
* 在队列末尾加入新的路点
*/
void CPlayer::push_way_point(int dest_x, int dest_y)
{
if ( m_way_points.empty() )
{
m_way_points.push_front( make_pair(dest_x, dest_y) ) ;
is_doing_task = true ;
}
else
{
m_way_points.push_front( make_pair(dest_x, dest_y) ) ;
}
}
/*
* 在队列头插入一个节点,改变当前路线
*/
void CPlayer::insert_way_point(int x, int y)
{
m_way_points.push_back( make_pair(x, y) ) ;
is_doing_task = true ;
}
double CPlayer::compute_dxy()
{
int dest_x ;
int dest_y ;
double min_length = 800 * 800 + 600 * 600 ;
double temp ;
int dx1 = (int)( context->GetWalkingSpeed() * cos(22.0 / 180 * PI) ) ;
int dy1 = (int)( context->GetWalkingSpeed() * sin(22.0 / 180 * PI) ) ;
int dx2 = (int)( context->GetWalkingSpeed() * cos(31.0 / 180 * PI) ) ;
int dy2 = (int)( context->GetWalkingSpeed() * sin(31.0 / 180 * PI) ) ;
dest_x = m_way_points.back().first ;
dest_y = m_way_points.back().second ;
// 在第一个方向try: 向上
if ( ( temp = ActiveLength( x+dx2, y-dy2, dest_x, dest_y ) ) < min_length )
{
way_point_dx = dx2 ;
way_point_dy = -dy2 ;
min_length = temp ;
this->facing = 2 ;
}
// 在第二个方向上try :向下
if ( ( temp = ActiveLength( x-dx2, y+dy2, dest_x, dest_y ) ) < min_length )
{
way_point_dx = -dx2 ;
way_point_dy = dy2 ;
min_length = temp ;
this->facing = 0 ;
}
// 在第三个方向try:向左
if ( ( temp = ActiveLength( x-dx1, y-dy1, dest_x, dest_y ) ) < min_length )
{
way_point_dx = -dx1 ;
way_point_dy = -dy1 ;
min_length = temp ;
this->facing = 3 ;
}
// 在第四个方向try:向右
if ( ( temp = ActiveLength( x+dx1, y+dy1, dest_x, dest_y ) ) < min_length )
{
way_point_dx = dx1 ;
way_point_dy = dy1 ;
min_length = temp ;
this->facing = 1 ;
}
// 如果都不能移动,停在原地
if ( min_length > sqrt(800.0 * 800.0 + 600.0 * 600.0) )
{
way_point_dx = 0 ;
way_point_dy = 0 ;
}
else
{
consist_way_time = rand() % 4 + 4 ;
this->state = CGameLogic::WALKING ;
}
return min_length ;
}
bool CPlayer::AutoUpdate()
{
// 检查动画是否播放完毕
CheckMovFrameEnd() ;
if ( is_dead )
{
return false;
}
if ( this == &(context->m_ActorManager->GetActiveActor()) )
{
// 如果是用户控制的人物,仅刷新用户关注的npc
this->context->m_ActorManager->RefreshUserAttention() ;
return false ;
}
// 如果是自动攻击模式,那么检测和ActiveActor的距离
if ( is_auto_attack && active_in_scene && !is_dead && !this->context->is_fighting() )
{
CPlayer& actor = context->m_ActorManager->GetActiveActor() ;
if ( !actor.is_dead )
{
vector<string> Argu ;
Argu.push_back(actor.name);
Argu.push_back(this->name);
if ( ActiveLength( actor.x, actor.y, this->x, this->y ) < context->GetSensitiveLength() * 1.2 )
{
this->context->m_EventManager->Call_Event( "fight", &Argu ) ;
this->context->m_EventManager->Continue_Doing() ;
}
}
}
// 是不是在等待模式,如果间隔时间不到就不继续执行
if ( waiting_mode )
{
if (timeGetTime() - start_time > waiting_time )
{
waiting_mode = false ;
}
else
{
return true ;
}
}
if ( is_doing_task && active_in_scene && !context->is_fighting() )
{
int dest_x = m_way_points.back().first ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -