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

📄 character.cpp

📁 3D游戏展示程序
💻 CPP
字号:
//--------------------------------------------------
//  Desc: Ride Horse & Change Clothes Character
//  Author: artsylee/2007.4.18
//--------------------------------------------------

#include "Character.h"
#include "Heightmap.h"
#include "Common.h"
#include "GameCommon.h"
#include "NodeAdjust.h"

extern CHeightmap g_Hmap;
extern CNodeAdjust	g_NodeAdjust;

#define EQUIP_CAMERA_OFFSET_Y	(-3.0f)
#define EQUIP_CAMERA_OFFSET_Z	(5.0f)
#define EQUIP_CAMERA_RADIUS		(-4.0f)
#define EQUIT_CAMERA_TIME		(1000.0f)

// model view camera base parameter
#define CAMERA_OFFSET_X	0.0f
#define CAMERA_OFFSET_Y	10.0f
#define CAMERA_OFFSET_Z	0.0f
#define CAMERA_RADIUS	20.0f


CCharacter::CCharacter():
m_vDirection(1.0f, 0.0f, 0.0f)
{
	m_bRun = false;
	m_bJump = false;
	m_fSpeed = 20.0f;
	m_fSpeedRate = 1.0f;
	m_fAngleSpeed = 1.5f;
	m_RideState = RS_NONE;
	m_JumpTimer.SetInterval(800);
}

CCharacter::~CCharacter()
{
}

void CCharacter::Load()
{
	m_Char.Load();
	m_Char.OnMount(m_RideState);
	CCameraLock::Load();
	m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(CAMERA_OFFSET_X, CAMERA_OFFSET_Y, CAMERA_OFFSET_Z));
	m_pMVCamera->SetCameraRadius(CAMERA_RADIUS);
	m_Char.AddChildNode(m_pMVCamera);
}

void CCharacter::LoadPlayer(bool bDefault /* = true */)
{
	D3DXVECTOR3 Pos(1291.0f, 0.0f, 3724.0f);
	float rot = AS_PI/2.0f*0.5;
	if(bDefault==false)
	{
		CIniFile save("Config\\Save.ini");
		Pos.x = save.ReadFloat("Save", "PosX", 1291.0f);
		Pos.z = save.ReadFloat("Save", "PosZ", 3724.0f);
		rot = save.ReadFloat("Save", "RotY", AS_PI/2.0f*0.5);
	}
	
	Pos.y = g_Hmap.GetHeight(Pos.x, Pos.z);
	m_Char.SetScale(D3DXVECTOR3(7.0f, 7.0f, 7.0f));
	m_Char.SetPosition(Pos);

	m_Char.SetRotateY(rot);
	m_Char.SetName("girl");

	// 计算朝向(默认面向X轴正向)
	m_vDirection.x = 1.0f;
	m_vDirection.y = 0.0f;
	m_vDirection.z = 0.0f;
	D3DXMATRIX	matRot = m_Char.GetDerivedOrientation();
	D3DXVec3TransformNormal(&m_vDirection, &m_vDirection, &matRot);

	m_bUpdateViewer = true;
	m_pMVCamera->RotateUpTo(GetCameraDestRadian());
}

void CCharacter::SavePlayer(void)
{
	CIniFile save("Config\\Save.ini");
	D3DXVECTOR3 pos = m_Char.GetDerivedPos();
	save.WriteFloat("Save", "PosX", pos.x);
	save.WriteFloat("Save", "PosY", pos.y);
	save.WriteFloat("Save", "PosZ", pos.z);
	m_Char.GetRotate(&pos);
	save.WriteFloat("Save", "RotY", pos.y);
	save.Save(NULL);
}

void CCharacter::NextRider(void)
{
	m_RideState++;
	if(m_RideState>2)	m_RideState = 0;
	OnRide();
}

void CCharacter::WalkRun(void)
{
	m_bRun = !m_bRun;
}

//---------------------------------------------------
// 角色控制
//---------------------------------------------------
void CCharacter::Update(void)
{
	OnEquip();

	if(GetCamera()==CT_MODELVIEW)
	{
		bool bAction = false;
		float speed;
		if(m_bRun)	speed = m_fSpeed*(m_fSpeedRate+0.5f);
		else		speed = m_fSpeed*m_fSpeedRate;

		if(g_stInputInfo.KeyValue == DIK_SPACE && m_bJump==false && m_RideState!=RS_DRAKE)
		{
			m_Char.GetCurModel()->SetAnimationByID(0, 0, 37, 1);
			m_Char.GetCurModel()->SetAnimationByID(0, 1, 39, 1);
			m_bJump = true;
			bAction = true;	
			m_JumpTimer.ReStart();
		}
		if(m_bJump==true && m_JumpTimer.TimeOut())
		{
			m_JumpTimer.Stop();
			m_bJump = false;
		}
		if(IsMouseDown(RBUTTON) && g_CursorOffsetX)
		{
			Turn(m_fAngleSpeed*g_CursorOffsetX);	
			m_Char.GetCurModel()->SetAnimationByID(0, 0, m_bRun?5:4);
			bAction = false;
		}	
		if(!m_Mode.m_bEdit)
		{
			bool bBack = false;
			if(IsKeyDown(DIK_W) || IsKeyDown(DIK_UP)&&(!g_NodeAdjust.IsActive()))	
			{ 
				Move(speed);	
				if(!m_bJump)
					m_Char.GetCurModel()->SetAnimationByID(0, 0, m_bRun?5:4);
				bAction = true;	

				// 镜头自动跟随
				if(m_bMouseRotateYEnd)
				{
					float fDeltaAngle = GetCameraDestRadian()-m_pMVCamera->GetYawAngle();//-AS_PI;

					while(fDeltaAngle>AS_PI)	{	fDeltaAngle -= AS_PI*2.0f;	}
					while(fDeltaAngle<-AS_PI)	{	fDeltaAngle += AS_PI*2.0f;	}

					if(abs(fDeltaAngle)<0.1f)
					{
						m_bMouseRotateYEnd = false;
					}
					else
					{
						if(fDeltaAngle>0.0f)
							m_pMVCamera->RotateUp(0.02f);
						else
							m_pMVCamera->RotateUp(-0.02f);
						m_bUpdateViewer = true;
					}
				}
			}
			if(IsKeyDown(DIK_S) || IsKeyDown(DIK_DOWN)&&(!g_NodeAdjust.IsActive()))	
			{ 
				Move(-speed);	
				if(!m_bJump)
				{
					if(m_RideState==RS_DRAKE)	m_Char.GetCurModel()->SetAnimationByID(0, 0, 0);
					else						m_Char.GetCurModel()->SetAnimationByID(0, 0, 13);	
				}
				bBack = true;
				bAction = true;
			}
			if((IsKeyDown(DIK_A) || IsKeyDown(DIK_LEFT)) && !bBack)	
			{ 
				Turn(-m_fAngleSpeed);	
				if(!m_bJump)
					m_Char.GetCurModel()->SetAnimationByID(0, 0, m_bRun?5:4);	
				bAction = true;
			}
			if((IsKeyDown(DIK_D) || IsKeyDown(DIK_RIGHT)) && !bBack)	
			{ 
				Turn(m_fAngleSpeed);	
				if(!m_bJump)
					m_Char.GetCurModel()->SetAnimationByID(0, 0, m_bRun?5:4);
				bAction = true;
			}
		}
		
		if(!bAction && !m_bJump)	m_Char.GetCurModel()->SetAnimationByID(0, 0, 0);
		if(IsMouseDown(LBUTTON)&&g_stInputInfo.MouseValue==RB_DOWN)
		{
			if(rand()%2)
				m_Char.GetChar()->SetAnimationByIndex(1, 0, 7, 1);
			else
				m_Char.GetChar()->SetAnimationByIndex(1, 0, 68, 1);
		}
	}
	if(!m_Mode.m_bEdit)	
	{
		CCameraLock::CameraControl();
	}
	CCameraLock::Update();

	m_Char.Update();
}

//---------------------------------------------------
// 显示角色
//---------------------------------------------------
void CCharacter::Render(void)
{
	m_Char.Render();
	if(g_NodeAdjust.IsActive())
		CCameraLock::RenderInfo();
//	DrawSingleLine(0, 136, 0xffffffff, false, "Pos direction : %f", GetDirectionRadian());
}

//---------------------------------------------------
// 前后移动
//---------------------------------------------------
void CCharacter::Move(float fSpeed)
{
	float fSpeedLen = fSpeed * g_ElapsedTime * 0.001f;
	m_Char.Translate(D3DXVECTOR3(m_vDirection.x*fSpeedLen, 0.0f, m_vDirection.z*fSpeedLen));
	D3DXVECTOR3 worldPos = m_Char.GetDerivedPos();	
	float height = g_Hmap.GetHeight(&worldPos);
	D3DXVECTOR3 pos;
	m_Char.GetPosition(&pos);
	pos.y = height;
	m_Char.SetPosition(pos);
	m_bUpdateViewer = true;
}

//---------------------------------------------------
// 左右转身某个角度
//---------------------------------------------------
void CCharacter::Turn(float fAngleSpeed)
{
	float fAngle = fAngleSpeed * g_ElapsedTime * 0.001f;
	float fTotal = m_Char.GetRotateY()+fAngle;
	m_Char.SetRotateY(fTotal);
	m_pCurCamera->RotateUp(fAngle);
	m_bUpdateViewer = true;
	// 计算新的朝向
	D3DXMATRIX	matRot;
	D3DXMatrixRotationY(&matRot, fAngle);
	D3DXVec3TransformNormal(&m_vDirection, &m_vDirection, &matRot);
}

//---------------------------------------------------
// 转身到某个角度(0.0-2PI)
// (正X轴为0.0, 负Z轴为PI/2)
// GetDirectionRadian()可获取角色角度
//---------------------------------------------------
void CCharacter::TurnTo(float fAngle)
{
	// 角色
	m_Char.SetRotate(D3DXVECTOR3(0.0f, fAngle, 0.0f));
	// 角色移动方向
	D3DXMATRIX	matRot = m_Char.GetDerivedOrientation();
	D3DXVec3TransformNormal(&m_vDirection, &D3DXVECTOR3(1.0f, 0.0f, 0.0f), &matRot);
	// 摄像机方向
	m_pMVCamera->RotateUpTo(GetCameraDestRadian());
	m_bUpdateViewer = true;
}

//---------------------------------------------------
// 骑乘
//---------------------------------------------------
void CCharacter::OnRide(void)
{
	m_Char.OnMount(m_RideState);
	// 不同骑乘时的摄像机控制
	if(m_RideState==RS_NONE)
	{
		m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(0.0f, 10.0f, 0.0f));
		m_pMVCamera->SetCameraRadius(20.0f);
		m_fSpeedRate = 1.0f;
	}
	if(m_RideState==RS_HORSE)
	{
		m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(0.0f, 15.0f, 0.0f));
		m_pMVCamera->SetCameraRadius(30.0f);
		m_fSpeedRate = 2.0f;
	}
	if(m_RideState==RS_DRAKE)
	{
		m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(0.0f, 15.0f, 0.0f));
		m_pMVCamera->SetCameraRadius(40.0f);
		m_fSpeedRate = 3.0f;
	}
}

//---------------------------------------------------
// 获取角色朝向在X-Z平面上的角度(0.0-2PI)
// (正X轴为0.0, 负Z轴为PI/2)
//---------------------------------------------------
float CCharacter::GetDirectionRadian(void)
{
	if(m_vDirection.x == 0.0f)	
		m_vDirection.x = 0.00001f;

	float fatan = atanf(m_vDirection.z/m_vDirection.x);
	if(m_vDirection.x>0.0f)
	{
		if(m_vDirection.z<0.0f)	fatan += AS_PI*2.0f;
	}
	else
		fatan += AS_PI;

	return AS_PI*2.0f-fatan;
}

//---------------------------------------------------
// 摄像机跟随角色时的目标角度(0.0-2PI)
// 控制摄像机转到该角度实现尾随角色
//---------------------------------------------------
float CCharacter::GetCameraDestRadian(void)
{
	float fDirectionAngle = GetDirectionRadian()-0.5f*AS_PI;

	while(fDirectionAngle>=AS_PI*2.0f)
	{
		fDirectionAngle -= AS_PI*2.0f;
	}
	while(fDirectionAngle<0.0f)
	{
		fDirectionAngle += AS_PI*2.0f;
	}

	return fDirectionAngle;
}

//---------------------------------------------------
// 进入换装系统
//---------------------------------------------------
void CCharacter::InEquip(void)
{
	if(!m_Mode.m_bEdit)
	{
		GUIShow(EQUIP_WINDOW, true);
		// reset to base model view camera
		m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(CAMERA_OFFSET_X, CAMERA_OFFSET_Y, CAMERA_OFFSET_Z));
		m_pMVCamera->SetCameraRadius(CAMERA_RADIUS);
		m_pCurCamera = m_pMVCamera;
		// reset ride state
		m_RideState = RS_NONE;
		OnRide();

		m_Mode.m_bEdit = true;
		m_Mode.m_bDynamicMode = ES_FADE_OUT;
		m_Mode.m_Start = g_GlobalTime;
		if(GetCameraDestRadian()>AS_PI)
			m_Mode.m_fCameraDelta = (-AS_PI)/EQUIT_CAMERA_TIME;
		else
			m_Mode.m_fCameraDelta = (AS_PI)/EQUIT_CAMERA_TIME;
		m_Mode.m_fOffsetZDelta = (EQUIP_CAMERA_OFFSET_Z)/EQUIT_CAMERA_TIME;
		m_Mode.m_fOffsetYDelta = (EQUIP_CAMERA_OFFSET_Y)/EQUIT_CAMERA_TIME;
		m_Mode.m_fCameraRadius = (EQUIP_CAMERA_RADIUS)/EQUIT_CAMERA_TIME;
	}
}

//---------------------------------------------------
// 退出换装系统
//---------------------------------------------------
void CCharacter::OutEquip(void)
{
	if(m_Mode.m_bEdit)
	{
		GUIShow(EQUIP_WINDOW, false);
		m_Mode.m_bDynamicMode = ES_FADE_IN;
		m_Mode.m_Start = g_GlobalTime;
		m_Mode.m_fCameraDelta = (AS_PI)/EQUIT_CAMERA_TIME;
		m_Mode.m_fOffsetZDelta = (-EQUIP_CAMERA_OFFSET_Z)/EQUIT_CAMERA_TIME;
		m_Mode.m_fOffsetYDelta = (-EQUIP_CAMERA_OFFSET_Y)/EQUIT_CAMERA_TIME;
		m_Mode.m_fCameraRadius = (-EQUIP_CAMERA_RADIUS)/EQUIT_CAMERA_TIME;
	}
}

//---------------------------------------------------
// 换装系统循环
//---------------------------------------------------
void CCharacter::OnEquip(void)
{
	if(m_Mode.m_bDynamicMode)
	{
		unsigned long elapsed = g_GlobalTime-m_Mode.m_Start;
		if(elapsed<=(unsigned long)(EQUIT_CAMERA_TIME))
		{
			TurnTo(0.0f);
			float y, z;
			float radius;
			if(m_Mode.m_bDynamicMode == ES_FADE_IN)
			{
				z = CAMERA_OFFSET_Z+EQUIP_CAMERA_OFFSET_Z;
				y = CAMERA_OFFSET_Y+EQUIP_CAMERA_OFFSET_Y;
				radius = CAMERA_RADIUS+EQUIP_CAMERA_RADIUS;
				m_pMVCamera->RotateUpTo(GetCameraDestRadian()+m_Mode.m_fCameraDelta*elapsed-AS_PI);
			}
			else
			{
				z = CAMERA_OFFSET_Z;
				y = CAMERA_OFFSET_Y;
				radius = CAMERA_RADIUS;
				m_pMVCamera->RotateUpTo(GetCameraDestRadian()+m_Mode.m_fCameraDelta*elapsed);
			}
			m_pMVCamera->SetOffsetParentPos(D3DXVECTOR3(0.0f, y+m_Mode.m_fOffsetYDelta*elapsed, z+m_Mode.m_fOffsetZDelta*elapsed));
			m_pMVCamera->SetCameraRadius(radius+m_Mode.m_fCameraRadius*elapsed);
		}
		else
		{
			if(m_Mode.m_bDynamicMode == ES_FADE_IN)
			{
				m_Mode.m_bEdit = false;
			}

			m_Mode.m_bDynamicMode = ES_NONE;
		}
	}
}

⌨️ 快捷键说明

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