📄 character.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 + -