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

📄 player.cpp

📁 大型3D游戏设计制作详析及源代码,游戏脚本,设计报告,技术报告,用户手册
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		int dest_y = m_way_points.back().second ;

		if ( test_goal() || ( abs(x - dest_x) < context->GetWalkingSpeed() && abs( y - dest_y ) < context->GetWalkingSpeed() ) )
		{
			// 到达一个目的地,弹出队列
			m_way_points.pop_back() ;

			if ( is_loop )
			{
				m_backup_way_points.push_front( make_pair(dest_x, dest_y) ) ;
			}

			if ( !m_way_points.empty() )
			{
				// 还有目标点在队列中,继续移动
				compute_dxy() ;
				x += way_point_dx ;
				y += way_point_dy ;
				consist_way_time-- ;

				this->EnterWaitingMode( 1000 ) ;
			}
			else
			{
				if ( is_loop )
				{
					m_way_points = m_backup_way_points ;
					m_backup_way_points.clear() ;

					compute_dxy() ;
					x += way_point_dx ;
					y += way_point_dy ;
					consist_way_time-- ;

					this->EnterWaitingMode( 1000 ) ;
				}
				else
				{
					// 没有目标点,结束移动
					is_doing_task = false ;
					this->state = CGameLogic::STOP ;
				}
			}
		}
		else
		{
			if (consist_way_time < 0)
			{
				compute_dxy() ;
			}
			consist_way_time -- ;

			// 按原路线不能走通就选择新路线
			if ( context->GetLogicalMapInfo( x + way_point_dx, y + way_point_dy ) == 0 )
			{
				compute_dxy() ;
			}
			if ( !this->DetectOtherActor(2 * way_point_dx, 2 * way_point_dy) )
			{
				x += way_point_dx ;
				y += way_point_dy ;
			}
			else
			{
				this->EnterWaitingMode( 5000 ) ;
			}
		}
	}

	return is_doing_task ;
}

/*
 *	动态计算地图两点间举例
 */
double CPlayer::ActiveLength(int x1, int y1, int x2, int y2)
{
	if ( context->GetLogicalMapInfo(x1, y1) != 0 )
	{
		return sqrt( (double)( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) ) ;
	}
	else
	{
		return 3e10 ;
	}
}

bool CPlayer::test_goal()
{
	int dest_x = m_way_points.back().first ;
	int dest_y = m_way_points.back().second ;

	int old_way_point_dx = way_point_dx ;
	int old_way_point_dy = way_point_dy ;
	int old_consist_way_time = consist_way_time ;

	double length = compute_dxy() ;

	if ( length <= context->GetWalkingSpeed() )
	{
		return true ;
	}
	else
	{
		way_point_dx = old_way_point_dx ;
		way_point_dy = old_way_point_dy ;
		consist_way_time = old_consist_way_time ;
		return false ;
	}
}

void CPlayer::set_task_loop(bool is_loop)
{
	this->is_loop = is_loop ;
}

void CPlayer::EnterWaitingMode(unsigned int time )
{
	this->state = CGameLogic::STOP ;

	way_point_dx = 0 ;
	way_point_dy = 0 ;

	waiting_time = time ;
	waiting_mode = true ;
	start_time = timeGetTime() ;
}

bool CPlayer::DetectOtherActor(int dx, int dy)
{
	// 枚举压栈
	context->m_ActorManager->push_enum_state() ;

	CPlayer* other = context->m_ActorManager->enumActor() ;
	bool flag = false ;

	while ( other != NULL ) 
	{
		if ( other != this && other->active_in_scene && ActiveLength( other->x, other->y, this->x + dx, this->y + dy ) <= context->GetSensitiveLength() )
		{
			flag = true ;
		}
		other = context->m_ActorManager->enumActor() ;
	}

	// 枚举出栈
	context->m_ActorManager->pop_enum_state() ;

	return flag ;
}

void CPlayer::push_script(std::string& ProcName )
{
	m_talking_script.push_back(ProcName) ;
}

string& CPlayer::TalkScript()
{
	size_t i ;

	switch( m_talk_state ) 
	{
	// 随机的时候,就随机取脚本执行
	case RANDOM :
		i = rand() % m_talking_script.size() ;
		return m_talking_script[i] ;
		break;
	case CONTINUAL:
		if ( m_current_words < m_talking_script.size() )
		{
			return m_talking_script[ m_current_words++ ] ;
		}
		else
		{
			return m_talking_script[ m_current_words-1 ] ;
		}
		break ;

	case CONDITIONAL :
			return m_talking_script[ m_current_words ] ;
		break;

	case LOOP :
		if ( m_current_words < m_talking_script.size() )
		{
			return m_talking_script[ m_current_words++ ] ;
		}
		else
		{
			m_current_words = 0 ;
			return m_talking_script[ m_current_words++ ] ;
		}
		break;
	default:
		throw runtime_error("Incredible error in CPlayer::TalkScript()") ;
		break;
	}
}

void CPlayer::SetTalkState(TalkState state)
{
	m_talk_state = state ;
}

void CPlayer::NextTalking(string& ProcName )
{
	vector<string>::iterator pos = find( m_talking_script.begin(), m_talking_script.end(), ProcName ) ;

	if ( pos != m_talking_script.end() )
	{
		m_current_words = pos - m_talking_script.begin() ;
	}
	else
	{
		throw logic_error("Required procedure is not in actor's list!") ;
	}
}

void CPlayer::SetInfoText(const std::string& info )
{
	m_attack_str_buf = info ;

	this->attack_str = m_attack_str_buf.c_str() ;

	GetFrameCount(&m_frame_count_for_info) ;
}

void CPlayer::CheckMovFrameEnd()
{
	size_t now_frame ;
	
	GetFrameCount( &now_frame ) ;

	// 检查停止播放信息字符
	if ( now_frame - m_frame_count_for_info > FRAMENUMFORTEXT && this->attack_str != NULL )
	{
		this->attack_str = NULL ;
	}

	// 检查停止播放人物动画
	if ( now_frame - m_frame_count_for_movie > FRAMENUMFORMOV && this->state == CGameLogic::FIGHTING )
	{
		this->state = CGameLogic::STOP ;
	}
}

void CPlayer::NpcFight(std::string& fighter_name )
{
	// Random选择攻击招数
	size_t selector = rand() % m_skills.size() ;

	Attack( m_skills.begin()->description, fighter_name ) ;
}

void CPlayer::PlayFightMovie()
{
	// 开始播放动画
	this->state = CGameLogic::FIGHTING ;

	GetFrameCount(&m_frame_count_for_movie) ;
}

void CPlayer::Attack(std::string& skill, std::string& name )
{
	SPropertyItem* attack_skill = this->Skill(skill) ;
	CPlayer& actor = this->context->m_ActorManager->GetActor( name ) ;
	stringstream info ;

	if ( attack_skill->name == "内定" )
	{
		if ( attack_skill->description == "法术:如沐春风" )
		{
			if ( Property("魔法力")->val + attack_skill->val > 0 )
			{
				this->ChangeProperty( "魔法力", attack_skill->val ) ;
				this->ChangeProperty( "生命力", this->Property("生命力上限")->val * 2 / 3 );

				info << "<size=8><color=65535>生命力恢复到66%!" ;
				SetInfoText( info.str() ) ;

				Speak("如沐春风") ;
			}
			else
			{
				// 法术失败
				info << "<size=8><color=255>法术失败!" ;
				SetInfoText( info.str() ) ;

				Speak("法术失败");
			}
		}
	}
	else
	{
		// 对对方造成伤害
		int val = - ( rand() % this->Property("攻击力")->val ) ;

		val += attack_skill->val ;
		actor.ChangeProperty(attack_skill->name, val) ;

		info << "<size=8><color=255>受到攻击: " << val ;

		// 对方播放信息字符
		actor.SetInfoText( info.str() ) ;

		// 自己播放攻击动画
		PlayFightMovie() ;

		// 播放声音
		Speak( "挥剑" ) ;
	}

	context->m_EventManager->Wait( FRAMENUMFORTEXT + 5 ) ;
}

void CPlayer::TryEscape(const std::string& name )
{
	vector<string>	Argu ;

	// 根据速度来判断是否能够逃脱
	int npc_speed = context->m_ActorManager->GetActor(name).Property("速度")->val ;
	int my_speed = Property("速度")->val ;

	Argu.push_back(this->name) ;
	Argu.push_back(name) ;

	if ( rand() % ( npc_speed + my_speed ) <= my_speed )
	{
		context->m_EventManager->Do_Event("escape_success", &Argu) ;
	}
	else
	{
		context->m_EventManager->Call_Event("escape_fail", &Argu) ;
	}
}

void CPlayer::ChangeProperty(const string& property, int val )
{
	SPropertyItem* item = this->Property( property ) ;
	SPropertyItem* topval = this->Property( property+"上限" ) ;

	item->val += val ;

	if ( item->val > topval->val )
	{
		item->val = topval->val ;
	}

	// 处理升级问题

	int upgrade_line = 100 * ( 1 << (this->Property("等级")->val - 1) ) ;
	if ( property == "经验" )
	{
		while ( item->val >= upgrade_line )
		{
			// 提升一个等级
			this->Property("等级")->val++ ;

			// 各项属性上限分别提升
			this->Property("生命力上限")->val += this->Property("+生命力")->val ;
			this->Property("魔法力上限")->val += this->Property("+魔法力")->val ;
			this->Property("速度上限")->val += this->Property("+速度")->val ;
			this->Property("攻击力上限")->val += this->Property("+攻击力")->val ;

			this->Property("速度")->val = this->Property("速度上限")->val ;
			this->Property("生命力")->val = this->Property("生命力上限")->val ;
			this->Property("魔法力")->val = this->Property("魔法力上限")->val ;

			upgrade_line = 100 * ( 1 << (this->Property("等级")->val - 1) ) ;

			// 播放音效
			Speak("升级") ;

			// 播放字幕
			this->SetInfoText("<size=10>等级 +1") ;
		}
	}
}

void CPlayer::Die()
{
	this->active_in_scene = false ;
	this->is_dead = true ;

	if ( this == &( context->m_ActorManager->GetActiveActor() ) )
	{
		context->m_is_dead = true ;
	}
}

void CPlayer::AutoAttack(bool val)
{
	this->is_auto_attack = val ;
}

void CPlayer::LearnSkill(const SPropertyItem& skill )
{
	m_skills.push_back( skill ) ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -