⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.cpp

📁 大型3D游戏设计制作详析及源代码,游戏脚本,设计报告,技术报告,用户手册
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************
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 + -