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

📄 fsm_camera.cpp.svn-base

📁 自己做的小游戏
💻 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 + -