D3D游戏编程系列(七):自己动手编写rpg游戏之第三人称视角的构建
来源:互联网 发布:c 高级编程教程 编辑:程序博客网 时间:2024/05/09 11:14
终于迎来了自己的最后一个游戏,RPG冒险游戏,这个应该也是当前在单机领域最火的游戏类型了吧,丰富的剧情配上动听的音乐,在加上华丽的画面和带劲的打斗,实在是一个让人心旷神怡的游戏啊,本文旨在塑造一个简单的rpg游戏,希望和大家一起分享这美妙的游戏编程世界。
当前的大部分rpg游戏都是以第三人称视角作为基础的,这个和第一人称略有不同,在Camera的构建上也不尽相同,所以我带大家走进第三人称视角的世界。
class CDXThirdCamera{public:void Create(D3DXVECTOR3 vEye,D3DXVECTOR3 vAt);void RorateY(float fAngle);void RorateAxis(float fAngle);void Scale(float fParam);void GetTransform(D3DXMATRIX *Matrix);void Walk(float fWalk);void Left(float fLeft);D3DXVECTOR3 GetEye();D3DXVECTOR3 GetAt();void SetEyeHeight(float iY);void SetAtHeight(float iY);void SetEye(D3DXVECTOR3 Eye);void SetAt(D3DXVECTOR3 At);private:D3DXVECTOR3 m_vEye;D3DXVECTOR3 m_vAt;};
第三人称视角需要满足哪些需求,视角的水平旋转,视角的垂直旋转和视角的缩放,于是便有了RotateY,RotateAxis和Scale三个函数,还要注意这里有两个成员变量:
D3DXVECTOR3 m_vEye;D3DXVECTOR3 m_vAt;m_vEye代表玩家视角,就是当前Camera所处的位置,而m_vAt便是需要观察的点,说白了就是游戏里玩家操控的人物所处的位置,这样,有了Eye和At便可以形成一个视图矩阵了。
那么我们首先来看下RotateY是怎么实现的:
void CDXThirdCamera::RotateY( float fAngle ){D3DXMATRIX mat,matY,matTrans;D3DXMatrixTranslation(&mat,-m_vAt.x,-m_vAt.y,-m_vAt.z);D3DXMatrixRotationY(&matY,fAngle*D3DX_PI/180);D3DXMatrixTranslation(&matTrans,m_vAt.x,m_vAt.y,m_vAt.z);mat=mat*matY*matTrans;D3DXVec3TransformCoord(&m_vEye,&m_vEye,&mat);}
大家可以看到,我这里没有自己计算,而是全部用了D3DX的函数来做的,首先将当前用户平移玩家视角所在的位置平移,以使玩家的观察点位于原点,然后让Y轴旋转一定角度,最后在平移回来,这样我们就可以产生玩家视角围绕当前人物(观察点)旋转的效果。好,我们再看一下RotateAxis函数是怎么实现的:
void CDXThirdCamera::RotateAxis( float fAngle ){D3DXVECTOR3 u=m_vEye-m_vAt;D3DXVECTOR3 v=D3DXVECTOR3(m_vAt.x,0,m_vAt.z)-m_vAt;D3DXVECTOR3 out;D3DXVec3Cross(&out,&u,&v);D3DXVec3Normalize(&out,&out);D3DXMATRIX mat,matAxis,matTrans;D3DXMatrixTranslation(&mat,-m_vAt.x,-m_vAt.y,-m_vAt.z);D3DXMatrixRotationAxis(&matAxis,&out,fAngle*D3DX_PI/180);D3DXMatrixTranslation(&matTrans,m_vAt.x,m_vAt.y,m_vAt.z);mat=mat*matAxis*matTrans;D3DXVec3TransformCoord(&m_vEye,&m_vEye,&mat);}
垂直旋转的话相对来说比较复杂,但是我仔细分析下原理也很简单,首先我们根据观察点到用户视角的向量与婧观察点并且垂直于XZ平面的向量做叉乘,得到的便是垂直于这两条向量的一条向量,然后利用D3DXMatrixRotationAxis这样一个旋转轴函数便可以得出新的玩家视角位置。最后我们看一下Scale缩放视角是怎么实现的:
void CDXThirdCamera::Scale( float fParam ){D3DXVECTOR3 vScale=m_vAt-m_vEye;m_vEye+=vScale*(1-fParam);}缩放的操作很简单,没有用到什么函数,就是一个简单的插值处理而已,效果还不错。好了,下面我们继续介绍Walk是如何实现的:
void CDXThirdCamera::Walk( float fWalk ){D3DXVECTOR2 Normal=D3DXVECTOR2(m_vAt.x,m_vAt.z)-D3DXVECTOR2(m_vEye.x,m_vEye.z);D3DXVec2Normalize(&Normal,&Normal);m_vAt+=D3DXVECTOR3(fWalk*Normal.x,0,fWalk*Normal.y);m_vEye+=D3DXVECTOR3(fWalk*Normal.x,0,fWalk*Normal.y);}
因为行走只是在x和z方向上的位移(y上也会有移动,但必须根据地图来算出当前x和z所处的位置y的大小),所以我们只要构建一个二维方向向量,单位化后它的长度便为1,然后和当前的Eye和At相加下便可得到新的位置大小了。于是Walk(1)便是向前走,那么Walk(-1)便是向后走了,这样就可以少写一个函数了。最后我们再来看下Left是如何实现的:
void CDXThirdCamera::Left( float fLeft ){D3DXVECTOR3 u=m_vEye-m_vAt;D3DXVECTOR3 v=D3DXVECTOR3(m_vAt.x,0,m_vAt.z)-m_vAt;D3DXVECTOR3 out;D3DXVec3Cross(&out,&u,&v);D3DXVec3Normalize(&out,&out);m_vAt+=D3DXVECTOR3(fLeft*out.x,0,fLeft*out.z);m_vEye+=D3DXVECTOR3(fLeft*out.x,0,fLeft*out.z);}
有了上面的基础,这段代码我相信大家应该很容易就可以看懂了吧。恩,下一节我将带给大家的是rpg游戏里战斗部分的重点:粒子系统。
本文有不足之处,还望大家多多指正。
- D3D游戏编程系列(七):自己动手编写rpg游戏之第三人称视角的构建
- D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建
- D3D游戏编程系列(九):自己动手编写rpg游戏之lua脚本的引入
- D3D游戏编程系列(五):自己动手编写第一人称射击游戏之室外场景的构建
- D3D游戏编程系列(八):自己动手编写rpg游戏之粒子系统
- D3D游戏编程系列(二):自己动手编写即时战略游戏之地图编辑器的制作
- D3D游戏编程系列(三):自己动手编写即时战略游戏之寻路
- D3D游戏编程系列(四):自己动手编写即时战略游戏之网络同步
- D3D游戏编程系列自己动手编写即时战略游戏之网络同步
- D3D游戏编程系列(四):自己动手编写即时战略游戏之网络同步
- 【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)
- D3D游戏编程系列(一):DXLib的介绍
- 游戏人物第三人称操控及视角转变
- 摄像机之RPG游戏中玩家第三视角
- RPG游戏人物视角控制,相机跟随
- unreal engine4官网demo学习:第三人称视角游戏
- pygame编写的坦克游戏(七)
- D3D之2D游戏编程(一)——D3D图形管道
- 开源代码分析技巧之一——打印调用逻辑
- ACM 博弈
- poj 1149 PIGS(最大流+经典构图)
- 较快速在一个数组中查找最大值和最小值(2)
- 【Nginx】Gzip 压缩配置
- D3D游戏编程系列(七):自己动手编写rpg游戏之第三人称视角的构建
- 如何利用eclipse传递args[]参数
- int 和 Integer互相转换
- win 下查看和关闭端口
- 关于修改 AchartEngine 源码的修改
- Matlab画图实现两个或多个legend,不同排版
- SMP 3.0 Roadmap
- 几种滤波算法的方法优缺点及算法实例程序
- 整理:Vim中:wq与:x的区别