3D相机使用教程
今天,我们将深入探讨Cocos2d-x中相机的使用。在Cocos2d-x 3.3版本中,引入了相机类,这在3D游戏开发中是不可或缺的。在3D游戏的立体世界里,摄像机就如同我们的眼睛,借助它,我们能够观察整个游戏世界。
相机原理与类型
相机原理
上图展示了3D游戏中透视投影相机的原理,游戏中的相机正是基于此原理实现的。
相机类型
在游戏中,相机一般分为两种类型:
- 透视相机:如上图所示,这是3D游戏中常见的相机类型,具有近大远小的效果。
- 正交投影相机:没有近大远小的效果,相机内任何位置的物体大小都相同,常用于角色属性面板中显示的角色模型。
相机的创建
透视投影相机
// 此处应插入创建透视投影相机的代码
下面说明参数的意义:
- FOV(视场角,field of view):可以理解为视线左右能看到的宽度(以角度计量)。
- 宽高比:决定相机画面的宽高比例。
- 近裁面和远裁面:距离相机比近裁面近或比远裁面远的物体,都不会被渲染到。
正交投影相机
// 此处应插入创建正交投影相机的代码
参数意义如下:
- 宽度:相机画面的宽度。
- 高度:相机画面的高度。
- 近裁面和远裁面:与透视相机相同,距离相机比近裁面近或比远裁面远的物体,不会被渲染到。
相机标记位设置
为了区分不同的相机,需要为相机设置一个标记位(FLAG)。在一些游戏应用中,通常会有多个相机,此时需要标记一个物体能被哪些相机“看到”,这就需要设置物体的CameraMask与相机的Flag对应。
Camera类中有_cameraFlag属性,为枚举类型,定义如下:
enum class CameraFlag
{
DEFAULT = 1,
USER1 = 1 << 1,
USER2 = 1 << 2,
USER3 = 1 << 3,
USER4 = 1 << 4,
USER5 = 1 << 5,
USER6 = 1 << 6,
USER7 = 1 << 7,
USER8 = 1 << 8,
};
Node类中有_cameraMask属性,当相机的_cameraFlag & _cameraMask为true时,该Node可以被该相机看到。例如,在相机创建代码中,若camera的CameraFlag设置为CameraFlag::USER1,且layer的CameraMask为2,则表示该layer只能被CameraFlag::USER1相机看到。若精灵的cameraMask是3,它能被cameraFlag为CameraFlag::USER1和CameraFlag::USER2的相机看到。需要注意的是,如果精灵是在layer设置cameraMask之后添加的,还需要手动设置精灵的cameraMask。
最后,要将相机添加到场景中,否则无法看到效果。
// 此处应插入将相机添加到场景中的代码
相机在游戏中的使用
在3D游戏中,相机通常有三种使用方式:
自由相机
这种相机常用于即时战略类型的游戏,如《魔兽争霸3》。它可以随鼠标移动,能看到游戏场景的任何位置。
在Cocos2d-x中实现自由相机,只需在移动函数中把屏幕移动的距离赋值给相机,让相机跟随移动。需要注意的是,屏幕上的上下移动相对于相机是前后移动,要把屏幕移动的
y值赋给相机的z,且方向相反(向下滑屏幕相机向前移动,上滑相机向后移动)。
相机拉近和拉远的实现:
第一人称相机
第一人称相机相当于我们眼睛看到的视角,常用于FPS类型的游戏,如《使命召唤》。在Cocos2d-x中实现第一人称相机,只需将相机的位置绑定到游戏中控制的角色上。使用sprite3d的移动代替屏幕滑动,即屏幕滑动控制sprite3d,再将sprite3d的移动赋给相机。
相机旋转代码示例:
// 向左旋转代码
// 向右旋转代码
第三人称相机
第三人称相机常用于MMORPG类型的游戏,大多数网游都采用这种相机。它是将第一人称相机的位置设定在控制角色身后一定距离的位置,以便看清操控的角色。在Cocos2d-x中的实现与第一人称相机类似,在得到角色位置赋值给相机后,再给相机的位置加上一个偏移量(用offset表示)。
移动和旋转的实现与第一人称相机相同。
总结
通过本教程,我们学会了在Cocos2d-x中创建相机,并了解了相机在游戏中的三种使用方式。这些内容只是入门级介绍,若想深入学习,可参考CppTest中的Camera Test代码,其中有详细的代码实现。希望大家能制作出优秀的3D游戏!