Cocos2d-x是一个二维(2D)游戏引擎。但在Cocos2d-x版本3开始,3D特性被加了进来并进行了改进。3D游戏市场非常巨大, Cocos2d-x正在添加3D开发所需的所有功能 。
3D技术
- Mesh(网格): 顶点,用于构造要渲染的形状和纹理。
- Model( 模型 ): 可以渲染的对象 ,它是风格的集合。在Cocos2d-x中就是Sprite3D对象。
- Texture( 纹理 ):三维模型的所有曲面和顶点都可以映射到纹理。大多数情况, 每个模型有多个纹理 , 在纹理图集中展开。
- Camera(照相机): 因为三维世界不是平面的,你需要设置一个相机来观察它。 使用不同的相机参数可以得到不同的场景。
- Light(灯光): 应用灯光使场景看起来逼真。 为了使一个物体看起来真实,颜色应该根据光线变化。 当你面对光明时,它是光明的,相反的是黑暗的。 照亮物体意味着根据光线计算物体的颜色。
Sprite3D对象
就像2D游戏,3D游戏也有Sprite对象。Sprite对象是任何游戏的核心基础。Sprite3D和Sprite唯一不同的是Sprite3D对象有3个轴,可以定位在x、y和z轴上。 Sprite3D在很多方面都像普通的Sprite一样工作。 加载并展示Sprite3D对象:
.c3b
3D文件可以用FBX-converter工具来创建
现在,让我们来循环旋转模型。为此,我们将创建一个操作并运行它:
要在Sprite或Sprite3D上设置定位点,请使用:
将三维模型附加到Sprite3D对象
请记住,三维模型是网格的集合。可以将三维模型附加到其他三维模型以创建丰富的效果。如添加武器到主角上,为了做到这一点,你需要找到武器将被添加的附着点。可以调用getAttachNode(attachment_point_name)函数来找到。 然后我们用addChild()将新模型作为子模型添加到附件点 。
交换三维模型
当做3D开发时,你可能要对你的模型做些动态改变 。这种改变可能是换装、 视觉线索 、通知用户关于模型的状态变化。 如果三维模型由网格组成,则可以使用getMeshByIndex()
和getMeshByName()
访问网格数据。 . 使用这些功能,可以实现像用武器或衣服交换角色一样的效果。
Animation动画
创建Animate3D
对象,使用动画。
多动画
同时运行多个动画。
上面这个例子有两个动画。第一个立刻执行,持续2秒,第二个在3秒后执行,持续5秒。
Animation speed动画速度
向前的动画速度是一个正整数,负速度则是相反的方向。
Animation blending动画混合
当使用多个动画时, 在每个动画之间自动应用混合。混合的目的是在效果之间创建平滑过渡。 给定两个动画A和B,动画A的最后几帧和动画B的前几帧重叠以使动画中的更改看起来自然。 默认的过渡时间是0.1秒。可以使用Animate3D::setTransitionTime修改过渡时间。
Cocos2d-x只支持关键帧之间的线性插值。 这将填充曲线中的间隙以确保路径平滑。如果在模型制作中使用其他插值方法,我们的内置工具fbx-conv将生成额外的关键帧以进行补偿。
Camera照相机
3D世界不是平的,我们需要使用照相机观察它。因此Camera对象在3D开发中是非常重要的。Camera对象继承Node,因此支持大多数相同的动作对象。有两类Camera对象: perspective camera (透视照相机)和orthographic camera(正交相机)。
- 透视照相机用于观看具有近到远效果的对象 。透视照相机的效果:在近处的物体会比较大,在远处的物体会比较小。
- 正交摄影机可以将其理解为将三维世界转换为二维表示。使用正交摄影机可以看到,无论对象距摄影机对象有多远,它们的大小都是相同的。游戏中的小地图通常使用正交摄影机渲染。另一个例子是自上而下的视图,可能是在地牢风格的游戏中。
每一个Scene
自动地创建一个默认的camera, 基于Director对象的投影特性 。如果你要更多的camera,可以用如下代码创建:
创建正交照相机
默认的Camera是透视照相机,如果要创建正交照相机,可以用如下代码来创建:
如:
从相机中隐藏对象
有时,我们并不想在照相机里显示所有对象。从一个照相机里隐藏一个对象其实也很简单,通过在Node(节点)上调用setCameraMask(CameraFlag)和在Camera上调用setCameraFlag(CameraFlag)即可:
Cubemap Texture立方纹理
立方体贴图纹理是六个单独的正方形纹理的集合,这些纹理放置在虚拟立方体的面上。它们通常用于在对象上显示无限远的反射,类似于“天空盒”在背景中显示遥远景物的方式。展开的立方体映射的外观 :
Cocos2d-x创建立方纹理的方法:
Skybox
Skybox是你整个场景的包装,它显示了你的几何之外的世界。你可以用一个天空盒来模拟无限的天空、山脉和其他现象。 创建Skybox:
Light光线
光线对于营造游戏的气氛和氛围非常重要。目前支持4种照明技术。
- Ambient Light(环绕光): AmbientLight对象将均匀地为场景中的所有对象应用灯光。效果就像办公室里的照明。灯光在头顶,当你看到办公室周围的物体时,你会看到它们在同一个灯光下。
- Directional Light(平行光、定向光): 平行光通常用于模拟光源,如阳光。当使用方向光时,请记住它的密度是相同的,不管你和它的关系是什么。当你直视太阳时,它是一种强烈的光,即使你朝任何方向移动几步 。
- Point Light点光源:点光源通常用于模拟灯泡、灯或火炬的效果。 点光源的方向是 从发光位置到点光源 。离光源近则亮,远则暗。
- Spot Light聚光源:聚光源通常用于模拟手电筒。:
遮光
在节点上使用照明遮罩仅对其应用特定的光源。例如,如果场景中有多个灯光,则节点只能由其中一个灯光而不是全部三个灯光照亮。可以使用setLightFlag(LightFlag)控制灯光影响哪些节点对象。需要注意的是,所有光源都是在一个过程中渲染的。由于移动平台性能问题,不建议使用多个光源。默认最大值为1。如果要打开多个光源,必须在info.plist中定义以下键:
Terrain地形
纹理用于表示高度图。最多可以使用4种纹理来混合地形、草地、道路等的细节。
HeightMap高度图
高度图对象是地形图的核心。与普通图像不同,高度图表示顶点的高度。它决定了地形的几何形状。
DetailMap详细图
DetailMap对象是确定地形细节的纹理列表,最多可以使用四个纹理。
AlphaMap字母表
AlphaMap对象是一个图像,其数据是细节贴图的混合权重。混合结果是最终地形的外观。
LOD(Level Of Detail)政策
地形使用一种称为细节层次(Level Of Detail,LOD)的优化技术。这是一种渲染技术,当对象与摄影机的距离增加时,它可以减少对其进行渲染的垂直(或三角形)数量。用户可以通过调用Terrain::setLODDistance(float lod1, float lod2, float lod3) 方法来设置到相机的距离。
相邻的地形对象块,其LOD不同,可能会产生裂纹伪影。地形提供了两个功能来避免它们:
Terrain::CrackFixedType::SKIRT: 将在块的每个边上生成四个类似裙子的网格。
Terrain::CrackFixedType::INCREASE_LOWER: 将动态调整每个块索引以无缝连接它们。
创建Terrain地形
以下代码片段创建一个玩家并将其放置在地形图上:
创建所有DetailMap对象,最多4个。我们需要将DetailMap对象传递给Terrain::DetailMap结构体:
用DetailMap对象创建TerrainData变量,并指定高度图文件路径和字母图文件路径:
传递TerrainData
对象给Terrain::create
,最后一个参数决定LOD政策:
如果你设置Terrain
对象照相机遮罩(camera mask)并添加到一个节点Node或一个场景Scene。这时要当心,Terrain
被添加到节点或场景后,就不能再用transform(translate,scale)。另外,如果在addChild方法之后做以上操作,可能会导致一个错误。
使用方法Terrain::getHeight(float x, float z, Vec3 * normal= nullptr)可以获得指定位置的高度。当你想把一个Sprite3D对象或任意节点放在地形图上时,这个方法特别有用。
射线地形交会试验将会计算指定位置的交点。
Terrain::CrackFixedType::SKIRT
会产生四个 每一块边缘都有裙状网格 。
Terrain::CrackFixedType::INCREASE_LOWER
将会动态调整每个块索引以无缝连接它们。