📄 fsm_camera.cpp.svn-base
字号:
#include <math.h>
#include <assert.h>
#include "fsm_camera.h"
#include "fsmmacros.h"
#include "fsm.h"
#include "msg.h"
#include "custom_time.h"
#include "util.h"
#include "player.h"
#include "camera.h"
#include "../gamedata/structs.h"
#include "../gamedata/gamedata.h"
#include "../ui/ui.h"
#include <windows.h>
//这一堆变量里有几个没用到,懒得找了。您自己看一下,不是什么重要的变量。
float tmpMouse;
float lengthToDest;
Vertex begPos, begLookat;
unsigned int timeToGetToDest, temp;
float v_x, v_y, v_z; //三个方向的分速度
void UpdateCameraFromPlayer();
void CalcNewPosition();
void ProcessCameraInput();
//float GetDistance3(Vertex a, Vertex b);
bool CameraProcessStateMachine( GameObject* go, unsigned int state, MsgObject* msg )
{
BeginStateMachine
OnEnter
SetState(STATE_CameraWithPlayer); //一开始时设置为跟随player
//===========================
State(STATE_CameraWithPlayer)
OnEnter
//设置角度
cRotX = 40;
cRotY = player.rotY + 180;
if (cRotY >= 360)
cRotY -= 360;
UpdateCameraFromPlayer(); //根据角度更新位置
OnUpdate
UpdateCameraFromPlayer();
OnMsg(MSG_CameraFree)
SetState(STATE_CameraFree);
OnMsg(MSG_CameraAuto)
SetState(STATE_CameraAuto);
OnMsg(MSG_CameraWithPlayer)
cRotX = 40;
cRotY = player.rotY + 180;
if (cRotY >= 360)
cRotY -= 360;
//==============================
//在这种状态下,摄像机是静止的,各种参数随便设
State(STATE_CameraFree)
OnEnter
OnMsg(MSG_CameraSetLookAt)
camera.lookat = msg->ex.pos;
OnMsg(MSG_CameraSetPosition)
camera.position = msg->ex.pos;
OnMsg(MSG_CameraSetUp)
camera.up = msg->ex.pos;
OnMsg(MSG_CameraWithPlayer)
SetState(STATE_CameraWithPlayer);
OnMsg(MSG_CameraAuto)
SetState(STATE_CameraAuto);
//==============================
//目前在这种状态下,是从一个地方匀速移动到另一个地方
//不管是更改摄像机的目的地,还是更改摄像机的位置,只要这两个位置不同,摄像机就会自动移动
State(STATE_CameraAuto)
OnEnter
cameraDest = camera.position;
OnUpdate
//如果没有到达目的地则更新位置
if (abs(camera.position.x-cameraDest.x) > 5.f ||
abs(camera.position.y-cameraDest.y) > 5.f || abs(camera.position.z - cameraDest.z > 5.f))
CalcNewPosition();
OnMsg(MSG_CameraSetDest)
//设置目的地,计算各方向分速度
cameraDest = msg->ex.pos;
temp = 1000 * GetDistance3D(camera.position, cameraDest);
v_x = (cameraDest.x - camera.position.x) * cameraMoveSpeed / temp;
v_y = (cameraDest.y - camera.position.y) * cameraMoveSpeed / temp;
v_z = (cameraDest.z - camera.position.z) * cameraMoveSpeed / temp;
//c_begT = curT;
//c_durT = 1000 * destDist / cameraMoveSpeed;
OnMsg(MSG_CameraSetLookAt)
//设置往哪里看
camera.lookat = msg->ex.pos;
OnMsg(MSG_CameraSetPosition)
camera.position = msg->ex.pos;
temp = 1000 * GetDistance3D(camera.position, cameraDest);
v_x = (cameraDest.x - camera.position.x) * cameraMoveSpeed / temp;
v_y = (cameraDest.y - camera.position.y) * cameraMoveSpeed / temp;
v_z = (cameraDest.z - camera.position.z) * cameraMoveSpeed / temp;
//c_begT = curT;
//c_durT = 1000 * destDist / cameraMoveSpeed;
OnMsg(MSG_CameraSetUp)
camera.up = msg->ex.pos;
OnMsg(MSG_CameraFree)
SetState(STATE_CameraFree);
OnMsg(MSG_CameraWithPlayer)
SetState(STATE_CameraWithPlayer);
EndStateMachine
}
void UpdateCameraFromPlayer()
{
ProcessCameraInput(); //首先根据玩家的鼠标更新两个角度
//摄像机看的位置就是player所在的位置,这一点是模仿魔兽世界
camera.lookat.x = player.pos.x;
camera.lookat.y = player.pos.y;
camera.lookat.z = player.pos.z;
//camera.lookat.x += runVector.z*sinf(player.rotY*0.0174533f) + runVector.x*cosf(player.rotY*0.0174533f);
//camera.lookat.z += runVector.z*cosf(player.rotY*0.0174533f) - runVector.x*sinf(player.rotY*0.0174533f);
Vertex tPos;
//计算摄像机的位置,摄像机在以player为球心的球面上移动,简单的三角函数就可计算出它的位置
tPos.x = camera.radius * (cosf(cRotX*0.0174533f) * sinf(cRotY*0.0174533f)) + camera.lookat.x;
tPos.y = camera.radius * (sinf(cRotX*0.0174533f)) + camera.lookat.y;
tPos.z = camera.radius * (cosf(cRotX*0.0174533f) * cosf(cRotY*0.0174533f)) + camera.lookat.z;
//如果摄像机跑到地面下面,则让它往上抬直到地面上方
while (tPos.y < map.getHeight(tPos.x, tPos.z) + 3.0f) { //跑到地面下面去了
cRotX += 0.01f;
if (cRotX > 89.0f)
break;
tPos.x = camera.radius * (cosf(cRotX*0.0174533f) * sinf(cRotY*0.0174533f)) + camera.lookat.x;
tPos.y = camera.radius * (sinf(cRotX*0.0174533f)) + camera.lookat.y;
tPos.z = camera.radius * (cosf(cRotX*0.0174533f) * cosf(cRotY*0.0174533f)) + camera.lookat.z;
}
camera.position = tPos;
//camera.position.x = camera.radius * (cosf(cRotX*0.0174533f) * sinf(cRotY*0.0174533f)) + camera.lookat.x;
//camera.position.y = camera.radius * (sinf(cRotX*0.0174533f)) + camera.lookat.y;
//camera.position.z = camera.radius * (cosf(cRotX*0.0174533f) * cosf(cRotY*0.0174533f)) + camera.lookat.z;
}
//float GetDistance3(Vertex a, Vertex b)
//{
// return sqrt(pow(a.x-b.x, 2) + pow(a.y-b.y, 2) + pow(a.z-b.z, 2));
//}
void CalcNewPosition()
{
//Vertex a = camera.position;
//Vertex b = cameraDest;
//float rot_y = atan2(b.z-a.z, b.x-b.x); //a,b两点在xz平面的投影的连线的斜率
//float a_w = 0; // w为a,b在xz平面的投影的连线的那个轴
//float b_w = (b.z-a.z) * sinf(rot_y) + (b.x-a.x) * cosf(rot_y);
//float rot_x = atan2(b.y-a.y, b_w-a_w);
//float v_y = cameraMoveSpeed * sinf(rot_x) * (GetCurTime()-preT); //速度在y轴的分量乘以时间
//float v_w = cameraMoveSpeed * cosf(rot_x); //速度在w轴的分量
//float v_x = v_w * cosf(rot_y) * (GetCurTime()-preT);
//float v_z = v_w * sinf(rot_y) * (GetCurTime()-preT);
//camera.position.x += v_x;
//camera.position.y += v_y;
//camera.position.z += v_z;
//camera.lookat.x += v_x;
//camera.lookat.y += v_y;
//camera.lookat.z += v_z;
//destDist = GetDistance(camera.position, cameraDest);
//timeToGetToDest = 100000 * destDist / cameraMoveSpeed;
//float incRatio = 100000 * incT / timeToGetToDest;
//float incRatio = 0.01f;
//float incX = incRatio * (cameraDest.x-begPos.x);
//float incY = incRatio * (cameraDest.y-begPos.y);
//float incZ = incRatio * (cameraDest.z-begPos.z);
//camera.position.x += incRatio * (cameraDest.x-begPos.x);
//camera.position.y += incRatio * (cameraDest.y-begPos.y);
//camera.position.z += incRatio * (cameraDest.z-begPos.z);
//camera.lookat.x += incRatio * (cameraDest.x-begLookat.x);
//camera.lookat.y += incRatio * (cameraDest.y-begLookat.y);
//camera.lookat.z += incRatio * (cameraDest.z-begLookat.z);
//camera.position.x = begPos.x + (curT - c_begT) / c_durT * (cameraDest.x - begPos.x);
//camera.position.y = begPos.y + (curT - c_begT) / c_durT * (cameraDest.y - begPos.y);
//camera.position.z = begPos.z + (curT - c_begT) / c_durT * (cameraDest.z - begPos.z);
//camera.lookat.x = begLookat.x + (curT - c_begT) / c_durT * (cameraDest.x - begLookat.x);
//camera.lookat.y = begLookat.y + (curT - c_begT) / c_durT * (cameraDest.y - begLookat.y);
//camera.lookat.z = begLookat.z + (curT - c_begT) / c_durT * (cameraDest.z - begLookat.z);
//上面的方法都不是很好。其实只要简单的加上分速度就成。
camera.position.x += incT * v_x;
camera.position.y += incT * v_y;
camera.position.z += incT * v_z;
camera.lookat.x += incT * v_x;
camera.lookat.y += incT * v_y;
camera.lookat.z += incT * v_z;
}
void ProcessCameraInput()
{
tmpMouse = mouseSpeed * incT;
//如果鼠标右键按下,更新摄像机的角度
if (key[MOUSE_1]) {
cRotX -= (CENTER_Y - mouseY) * tmpMouse; //摄像机的上下移动
cRotY -= (mouseX - CENTER_X) * tmpMouse; //摄像机的左右转动
SetCursorPos(CENTER_X,CENTER_Y); //设置为屏幕中心
mouseX = CENTER_X;
mouseY = CENTER_Y;
}
if (cRotX > 89.9f) cRotX = 89.9f;
if (cRotX < -89.9f) cRotX = -89.9f;
if (cRotY >= 360) cRotY -= 360;
if (cRotY < 0) cRotY += 360;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -