Cocos2d-x 的3D游戏制作官方教程(中文翻译)
相信,你已经对Cocos2d-x有所了解,并且将它作为一种2D游戏引擎来看待。但是,从版本3开始,我们已经将3D一些特性添加到了Cocos2d-x里面。因为3D游戏是一个巨大的市场,所以,为了方便您进行3D游戏的开发,Cocos2d-x向您提供了所有你开发3D游戏时所需要的特性。或许对你而言,3D开发是一个新的领域,这里有一些软件、工具是你所需要了解了。 深吸一口气,不要紧张,我们将一步一步地带你走进3D开发的奇妙之旅! 1. Sprite3D跟2D游戏一样,3D游戏开发同样也需要Sprite对象。Sprite对象是所有游戏的一个基础构件。3D Sprite相比于2D,除了x轴跟y轴,还多了一个z轴。Sprite3D的大部分用法都跟图片的Sprite没有两样。加载并显示一个Sprite3D对象非常简单,看代码: auto sprite = Sprite3D::create("boss.c3b");
sprite->setScale(5.f);
sprite->setPosition(Vec2(200,200));
scene->addChild(sprite);
以上代码,非常简单的就创建了一个Sprite3D对象,显示效果如下: 2. 专有名词虽然并不涉及语言范畴,但是,在使用3D特性的时候,你还是需要了解这个领域的一些被广泛使用的专有名词。
3. 使用Sprite3D3.1 将3D模型载入到Sprite3D对象上文已经提到,3D模型是一系列的mesh集合。你可以将一个3D模型附加到另一个3D模型中,以此来产生一些丰富的特效。比如,你可以将一个武器模型附加到任务模型中。为了达到这个效果,你需要找到武器需要附加的位置。在代码中,你可以使用 getAttachNode() 来进行添加。 auto sp = Sprite3D::create("axe.c3b");
sprite->getAttachNode("Bip001 R Hand")->addChild(sp);
代码显示的效果如下: 3.2 互换 3D Model当进行3D开发的时候,你可以想要对模型进行动态的修改。比如,当人物能力值的变化,服装的改变,或者你想要通过模型在视觉上的变化来提醒用户状态的改变。如果你的3D模型是由mesh构成的,那么你可以使用 getMeshByIndex() 和 getMeshByName() 轻松的访问这些mesh。通过这些函数,你可以实现人物更换武器或者服装的效果。 我们可以通过改变一系列mesh对象,来更换女孩穿着的外套。下面的代码演示了如何实现这一功能: auto sprite = Sprite3D::create("ReskinGirl.c3b");
// display the first coat
auto girlTop0 = sprite->getMeshByName("Girl_UpperBody01");
girlTop0->setVisible(true);
auto girlTop1 = sprite->getMeshByName("Girl_UpperBody02");
girlTop1->setVisible(false);
// swap to the second coat
girlTop0->setVisible(false);
girlTop1->setVisible(true);
上述代码的演示效果如下: 4. AnimationSprite3D 对象是构成游戏最本质的对象。我们已经在前面学会了如何操作它们。但是,你可能还想要一些更丰富的效果体验。加入一些动画效果吧!为了执行了一个动画效果,你需要使用 Animation3D 和 Animation3D 对象。然后,你可以使用 Animation3D 对象来创建一个Animate3D动作效果。来看例子: // the animation is contained in the .c3b file
auto animation = Animation3D::create("orc.c3b");
// creates the Action with Animation object
auto animate = Animate3D::create(animation);
// runs the animation
sprite->runAction(RepeatForever::create(animate));
文字无法展示动画效果,所以,你还是使用”Programmer Guide Sample”中的代码,来亲自体验这个动画特效吧!需要注意的是,3D动画和2D动画有共通之处,可以回到第4章再仔细研读一番。 4.1 多个动作如果你想要在同一时间执行多重动作效果的时候,你该怎么做? auto animation = Animation3D::create(fileName);
auto runAnimate = Animate3D::create(animation,0,2);
sprite->runAction(runAnimate);
auto attackAnimate = Animate3D::create(animation,3,5);
sprite->runAction(attackAnimate);
在上面的例子中,有两个动画特效得到了执行。第一个动作立刻执行,并执行了2秒钟。第二个在开始后的三秒钟才开始执行,并持续了5秒钟。 4.2 动画执行速度动画的速度属性是一个正数,当然也有负数的速度,表示反方向。在这个例子中,速度被设定为10,这表示动画长度是10秒。 4.3 动画混合当你使用多重动画的时候,每个动画之间的融合协调是自动进行的。动画融合的目的是在不同动画效果之间进行平滑过度。给定两个动画,A和B,在动画A的最后几帧,和B的前几帧会重叠,使得动画看起来的效果更自然。 5. CameraCamera对象是3D开发中非常重要的一个部分。因为3D世界并不是平面的,所以你需要一个Camera来观察、导航,这就像你正在看一场电影,通过不同的镜头看到不同的场景。在使用Camera对象的时候,你需要有这样的概念。Camera对象是从Node继承而来的,因此,它同样可以支持大多数的动作对象。需要注意的是,Camera对象分为两种,一种是透视Camera,另一种是正交投影Camera. 通过这个透视Camera,你可以看到物体越近看起来越大,反之看起来更小。 你可以看到不管物体有多远,它的尺寸还是一样的。例如,如果游戏的地图很小,通常会使用正交投影Camera来渲染。 5.1 Camera 的使用不要紧张,可能Camera对象听起来很复杂,但是放心,我们已经确保你使用它进行开发的时候会很轻松。实际上,当使用3D的开发的时候,你完全不需要做什么来创建一个Camera对象。每一个场景都会根据Director对象的映射属性自动生成一个默认的Camera。如果你需要不止一个Camera,你可以使用下面的代码来再创建一个: auto s = Director::getInstance()->getWinSize();
auto camera = Camera::createPerspective(60,(GLfloat)s.width/s.height,1,1000);
// set parameters for camera
camera->setPosition3D(Vec3(0,100,100));
camera->lookAt(Vec3(0,0),Vec3(0,0));
addChild(camera); //add camera to the scene
5.2 创建一个正交投影Camera默认的Camera是透视Camera。如果你想要创建一个正交投影的Camera,也非常简单,只需要使用 Camera::createOrthographic(). 例如: auto s = Director::getInstance()->getWinSize();
auto camera = Camera::createOrthographic(s.width,s.height,1000);
5.3 Hide objects from camera有时候,你并不想将所有的物体都显示到视野中。在Cocos2d-x 中,想要隐藏一个物体非常简单,使用如下操作即可: //Camera
camera->setCameraFlag(CameraFlag::USER1);
//Node
node->setCameraMask(CameraFlag::USER1);
6. Light如果你想要你的游戏更精美,画面的氛围更真实,控制好Light同样是一件非常重要的事情。目前Cocos2d-x支持4中光照技术。你可以根据你的需要,选择最适合你的光照技术。每一种光照效果都是不同的。 6.1 Ambient Light(环境光)环境光没有固定的位置,也没有具体的方向。使用环境光可以为模型的每个表面都提供相同的照明,每个表面都显示出同样的亮度。想象一下你在办公室的环境中,所有地方都有光,你看到的所有物体的光照情况都是一样的。想要使用环境光照,可以按如下做法: auto light = AmbientLight::create (Color3B::RED);
addChild (light);
它产生的效果如下: 6.2 Directional Light(定向光/平行光)定向光通常被用来模拟类似太阳光的光源。定向光源是沿着同一方向发射的平行光线,因此定向光光也没有固定的位置,而是沿着指定的方向无限延伸。当你使用定向光的时候,你需要意思到对于每一个被定向光照射的表面,其光线强度都与光源处相同。想象一下,你在晴朗的户外,当你直视太阳的方向,即使你走了几步,光照还是一样强烈。使用定向光可以如下操作: auto light = DirectionLight::create(Vec3(-1.0f,-1.0f,0.0f),Color3B::RED);
addChild (light);
它产生的效果如下: 6.3 Point Light(点光源)点光源通常被用来模拟灯泡,灯或者火炬的光照效果。点光源从一点出发向所有方向发射光线,类似于灯泡所发出的光线。点光源的位置决定了光线与模型各个表面的夹角,因此可以在不同位置指定多个点光源,提供不同的光照效果。此外,点光源的强度可以随着距离的增加而进行衰减,并且可以使用不同的衰减方式,从而可以更加逼真地模拟实际的光照效果。使用点光源可以如下操作: auto light = PointLight::create(Vec3(0.0f,0.0f,Color3B::RED,10000.0f);
addChild (light);
它产生的效果如下: 6.4 Spot Light(聚光灯)聚光灯通常被用作模拟手电筒的效果。聚光灯从一点出发,沿指定的方向和范围发射具有方向性的圆锥形光束。聚光灯所产生的圆锥形光锥分为两部分:内部光锥是光束中最亮的部分,其顶角称为聚光角;整个光锥的顶角称为照射角,在照射角和聚光角之间的光锥部分,光的强度将会产生衰减,这一区域称为快速衰减区。同点光源一样,聚光灯的强度也可以从光源开始,随着光线传播距离的增加而逐渐衰减,并且可以使用不同的衰减方式。使用聚光灯可以如下操作: auto spotLight = SpotLight::create(Vec3(-1.0f,Vec3(0.0f,0.0,0.5,10000.0f) ;
addChild (spotLight);
它产生的效果如下: 6.5 Light Masking(光罩)你在你的厨房或者卧室使用什么样的照明?可能是几盏灯?你是否注意到,或许你只使用了一个灯就能把整个房间照亮?那是因为你使用了灯罩! <key> cocos2d.x.3d.max_dir_light_in_shader </key>
<integer> 1 </integer>
<key> cocos2d.x.3d.max_point_light_in_shader </key>
<integer> 1 </integer>
<key> cocos2d.x.3d.max_spot_light_in_shader </key>
<integer> 1 </integer>
7. 3D 软件包7.1 3D 编辑器3D编辑器包含了你创建3d图形的各种工具。这里提供包括商业版和免费版的一下主流的编辑器:
大部分3D编辑器,通常保存的文件可以在各个编辑器之间互用,而且也可以导入到游戏引擎中使用的。 7.2 Cocos2d-x 提供的工具Cocos2d-x 提供一些工具来帮你将你的3D模型转化成Cocos2d-x能够访问的文件格式。 7.3 fbx-conv 命令行工具fbx-conv 能够帮你将FBX文件转换成Cocos2d-x 特有的格式(c3t,c3b)。FBX是最流行的3D文件格式,主流的3D编辑器基本都支持这一文件格式。使用 fbx-conv 非常简单,你只需要提供几个参数即可: fbx-conv [-a|-b|-t] FBXFile
可供选择使用的参数如下:
fbx-conv -a boss.FBX
这里还需要注意一些小细节:模型需要有一个至少包含一个纹理图案的材质;而且目前只支持一个骨骼动画,多个骨骼对象现在还不能被支持。但是,你可以创建一个3d场景,然后后导出多个静态模型。mesh最多支持的顶点数是32767. 8. 3D 文件格式Cocos2d-x 目前提供两种3d文件格式:
Wavefront文件格式是一种应用十分广泛的格式,主流的3D编辑器都支持它,而且它能够很简单被解析。但是,它也有局限性,比如它不支持动画特性。 9. 高级模块9.1 BillBoard或许,在此之前,你根本没有听说过BillBoard(翻译为广告牌)。不要误会,我不是再说你在高速路上总是看到的令人厌恶的广告牌。我说的BillBoard是一个特殊的Sprite,它总是面对着Camera。当你旋转Camera的时候,BillBoard对象也会随之一起旋转。使用BillBoard是一个十分普遍的渲染技术。举个例子:高山滑雪游戏。在这种游戏中,滑雪者道路上出现的任何树、石头或者其他问题都是BillBoard对象。下图演示了Camera跟BillBoard对象之间的关系: 9.2 BillBoard的使用Billboard 对象可以被很轻松地创建。BillBoard衍生自Sprite,所以Sprite拥有的大部分特性,它也都支持。我们可以使用以下方法来创建BillBoard: auto billboard = BillBoard::create("Blue_Front1.png",BillBoard::Mode::VIEW_POINT_ORIENTED);
通过改变BillBoard对象的类型,你可以创建一个XOY平面上的BillBoard对象: auto billboard = BillBoard::create("Blue_Front1.png",BillBoard::Mode::VIEW_PLANE_ORIENTED);
上面的两种方法,差异只在于传递了不同的 BillBoard::Mode 类型,一个是 _VIEW_POINT_ORIENTED 第二个是 VIEW_PLANE_ORIENTED. VIEW_POINT_ORIENTED 表示BillBoard对象是朝向Camera的,其效果如下: VIEW_PLANE_ORIENTED 表示BillBoard对象是朝向XOY平面的,其效果如下: billboard->setScale(0.5f);
billboard->setPosition3D(Vec3(0.0f,0.0f,0.0f));
billboard->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
addChild(billboard);
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |