`
shuai1234
  • 浏览: 972265 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

Cocos2d-x中的3D功能

 
阅读更多

或许你已经开始接触Cocos2d-x了,并且已经知道它是一个2D游戏引擎。从3.x版本开始,Cocos2d-x已增加并改进了3D功能。3D游戏有着巨大的市场,所以Cocos2d-x中添加了3D开发所需的所有功能。或许3D开发对你来说是个新事物,并且很多专业术语你都不熟悉。但这篇文章会让你熟悉一些额外的软件工具,下面就让我们一起来了解了解Cocos2d-x中的3D功能吧。

初学3D

Sprite3D

正如2D游戏一样,3D游戏中也有Sprite对象。理所当然地,任何游戏的核心基本对象都是Sprite对象。3D精灵不仅有x、y轴,还有z轴。与常见的Sprite一样,Sprite3D有多种方式。加载并显示一个Sprite3D对象很容易:

  1.  
    auto sprite = Sprite3D::create("boss.c3b");
  2.  
    sprite->setScale(5.f);
  3.  
    sprite->setPosition(Vec2(200,200));
  4.  
    scene->addChild(sprite);

以上代码基于提供的文件创建了一个Sprite3D对象。运行如下: 9_1.jpg

术语

这里并没有一个语言类,但是当使用3D时,你需要了解一些常用术语。

  • Mesh(网格):构建一个shape的顶点,以及对应的渲染纹理。

  • Model(模型):可被渲染的对象,它也是网格的集合。在Cocos2d-x引擎中,我们称之为“Sprite3D”

  • Camera(摄像机):3D场景不是平面的,所以你需要设置一个摄像机。不同场景的摄像机参数是不同的。

  • Light(光线):光线用于使场景看上去更加接近真实世界。游戏中的对象如果要看上去更加真实,那么它的颜色必须随着光线而变化。面对光线是亮的,而背对光线时就该是暗的。用光线照射一个对象意味着这个对象必须根据光线来计算它的颜色。

使用Sprite3D

给Sprite3D对象添加3D模型

上文中提到3D模型是网格的集合。所以你可以将一个3D模型添加到其他的3D模型上,从而创建出丰富的效果。我们来举一个给对象添加武器的例子。首先需要找到武器要添加到的附着点,这个可以使用getAttachNode(attachment_point_name) 函数来实现。然后需要使用addChild()函数将这个新模型作为一个子节点添加到附着点上。你可以把以上过程理解为将多个简单的3D模型组合起来创建更复杂的模型。将模型添加到Sprite3D对象上的例子如下:

  1.  
    auto sp = Sprite3D::create("axe.c3b");
  2.  
    sprite->getAttachNode("Bip001 R Hand")->addChild(sp);

9_3.jpg

更换3D模型

当进行3D建模时,你或许想要给模型添加动态变化。也许道具、外观的变化或视觉信号会使用户注意到=模型状态的改变。

如果3D模型是由网格组成的,可以使用getMeshByIndex()getMeshByName()来访问网格数据。使用这些函数可以实现更换武器或者改变对象外观的效果。如下图中我们给女孩穿上一件外套:

9_4.jpg

改变正在使用的网格对象的可见度就可以改变女孩所穿的外套。下面的示例将演示如何实现这个效果:

  1.  
    auto sprite = Sprite3D::create("ReskinGirl.c3b");
  2.  
     
  3.  
    // display the first coat
  4.  
    auto girlTop0 = sprite->getMeshByName("Girl_UpperBody01");
  5.  
    girlTop0->setVisible(true);
  6.  
     
  7.  
    auto girlTop1 = sprite->getMeshByName("Girl_UpperBody02");
  8.  
    girlTop1->setVisible(false);
  9.  
     
  10.  
    // swap to the second coat
  11.  
    girlTop0->setVisible(false);
  12.  
    girlTop1->setVisible(true);

结果:

9_4_0.jpg

动画

Sprite3D对象是游戏的核心。我们已经学到了如何操作精灵。然而,我们还需要更复杂的操作,例如动画!你可以使用Animation3D和Animate3D对象来运行一个3D动画。然后使用Ainmation3D对象来创建一个Animate3D动作。例如:

  1.  
    // the animation is contained in the .c3b file
  2.  
    auto animation = Animation3D::create("orc.c3b");
  3.  
     
  4.  
    // creates the Action with Animation object
  5.  
    auto animate = Animate3D::create(animation);
  6.  
     
  7.  
    // runs the animation
  8.  
    sprite->runAction(RepeatForever::create(animate));

运行《开发者指南示例》中的代码可以看到这个动作效果。请记住3D动画与2D中的概念完全相同,请参考开发者指南中的第四章

多个动画

同时运行多个动画的时你打算怎么做呢?你可以使用animation start time和animation length这两个参数来创建多个动画。这两个参数的单位都是秒。例如:

  1.  
    auto animation = Animation3D::create(fileName);
  2.  
     
  3.  
    auto runAnimate = Animate3D::create(animation, 0, 2);
  4.  
    sprite->runAction(runAnimate);
  5.  
     
  6.  
    auto attackAnimate = Animate3D::create(animation, 3, 5);
  7.  
    sprite->runAction(attackAnimate);

上例中有两个动画在运行。第一个动画立即运行并持续2秒。第二个动画在3秒后开始并持续了5秒。

动画速度

动画的速度为正整数时动画前进,为负数时动画后退。在这个例子中动画速度设置为10。这意味着该动画持续10秒。

混合动画

当使用多个动画时,混合效果将自动应用于各个动画之间。混合的目的是在特效之间创建一个平滑的过渡效果。例如现在有两个动画,分别是A和B。动画A的最后一帧和B动画的第一帧重叠以使动画之间的改变看上去更自然。

默认过渡时间为0.1秒。当然也可以使用Animate3D::setTransitionTime方法来设置过渡时间。

Cocos2d-x只支持关键帧之间的线性插值,这填补了曲线中的空缺以确保有一个平滑的路径。如果你在制作模型过程中使用了其他插值方法,我们的建模型工具 fbx-conv 将产生额外的关键帧来弥补,这种弥补将根据目标帧实现。更多关于fbx-conv的信息请在本章最后讨论。

摄像机

Camera对象在3D建模中非常重要。3D世界不是一个平面,需要使用 Camera 作为3D世界的导航。正如我们在看电影时屏幕面板的左右切换一样,这个概念同样适用于 Camera对象。Camera对象继承自Node,因此支持大部分的Action对象。Camera对象有两种类型:透视(perspective)摄像机和正交(orthographic)摄像机。

透视摄像机用于查看具有远近特效的对象。透视摄像机的视角看上去是这样:

PerspectiveCamera.jpg

正如你所看到的,使用透视摄像机物体在近处看上去较大,在远处看上去较小。

正交摄像机用于查看在较远距离处的对象。你可以将其想象成它将3D世界转换到2D视角。正交摄像机的视角看上去是这样:

OrthographicCamera.jpg

正如你所见,使用正交摄像机时,无论离Camera对象多远,物体大小不变。游戏中的迷你地图通常使用正交摄像机渲染。或者像地牢游戏中的由上到下的视角也是使用正交摄像机。

摄像机的使用

不要担心!Camera对象听起来很复杂,但是在Cocos2d-x中使其变得很简单。当使用3D时,创建一个Camera对象没有什么不同。基于Director对象的投影属性,每个Scene都会自动地创建一个默认摄像机。如果你还需要其他摄像机,你可以通过如下方法创建:

  1.  
    auto s = Director::getInstance()->getWinSize();
  2.  
    auto camera = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000);
  3.  
     
  4.  
    // set parameters for camera
  5.  
    camera->setPosition3D(Vec3(0, 100, 100));
  6.  
    camera->lookAt(Vec3(0, 0, 0), Vec3(0, 1, 0));
  7.  
     
  8.  
    addChild(camera); //add camera to the scene

创建正交摄像机。

默认摄像机为透视摄像机。如果需要创建正交摄像机,那么使用Camera::createOrthographic()会很简单,如下:

  1.  
    auto s = Director::getInstance()->getWinSize();
  2.  
    auto camera = Camera::createOrthographic(s.width, s.height, 1, 1000);

从摄像机中隐藏对象

有时我们不需要所有的对象都显示在摄像机的视图中。从摄像机中隐藏对象非常简单。只需要对节点设置setCameraMask(CameraFlag),对摄像机设置setCameraFlag(CameraFlag)。例如:

  1.  
    //Camera
  2.  
    camera->setCameraFlag(CameraFlag::USER1);
  3.  
     
  4.  
    //Node
  5.  
    node->setCameraMask(CameraFlag::USER1);

光对于创建游戏格调和氛围非常重要。目前Cocos2d-x支持4种光线,开发者根据需要可使用不同的光线,每种光线实现了不同的效果。

Ambient Light

AmbientLight对象将光应用于整个场景中。将光线比作为一个办公环境。所有的灯都在天花板上,你所看到的办公室中的每一个对象都处于同样的光线中。例如:

  1.  
    auto light = AmbientLight::create (Color3B::RED);
  2.  
    addChild (light);

效果:

9_9_1.jpg

Directional Light

DirectionalLight对象通常用于模拟一种无限远的光源,例如太阳光。使用DirectionalLight时要记住,无论在什么情况下使用,其密度都是相同的。可以想象成如果你站在室外的太阳光下,太阳光就会直射到你。当你直视太阳时,即便你在任一方向移动一小步,太阳光都会非常的强烈。示例:

  1.  
    auto light = DirectionLight::create(Vec3(-1.0f, -1.0f, 0.0f),
  2.  
    Color3B::RED);
  3.  
    addChild (light);

效果:

9_9_2.jpg

Point Light

PointLight对象通常用于模拟灯泡、灯或者手电筒的效果。PointLight的方向是从光点的位置照射出来的。 
要知道,根据距离PointLight的远近,光线的密度是不同的。这是什么意思呢?意思是指,如果你离PointLight的起始位置比较近,那么光线会比较强烈。如果你离PointLight的终点位置比较近,那么光线就比较暗。当然,投影的距离越大,PointLight的光线就越弱。例如:

  1.  
    auto light = PointLight::create(Vec3(0.0f, 0.0f, 0.0f), Color3B::RED, 10000.0f);
  2.  
    addChild (light);

效果:

9_9_3.jpg

Spot Light

SpotLight对象通常用于模拟类似手电筒的聚光效果。这意味着它只在一个方向发射的锥形状光源。想象一下如果在你的房子中有这种光源,那你可能正在拿着一个手电筒到地下室去重置东西。手电筒产生锥状的照明模式,你只能看到锥状内的物体。另外一个在黑暗环境中的例子,比如基于地牢的游戏中可以看到火把的位置在哪儿,而你却只能看到手电筒发射出来的有限的圆锥形范围。例如:

  1.  
    auto spotLight = SpotLight::create(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
  2.  
    Color3B::RED, 0.0, 0.5, 10000.0f) ;
  3.  
    addChild (spotLight);

效果:

9_9_4.jpg

Light Masking

在厨房或者卧室中你用什么光?可能有几个灯?你是否曾注意过在房间中只用一个灯来照亮某个部分?实际上这是在应用Light Masking!

light masking作用于Node上,只应用于特定的照明光源上。例如,如果在一个场景中有三个光源,一个节点只能被一个光源照亮,而不是三个。可以用setLightFlag(LightFlag);函数控制哪个节点对象被光源照到。重要是所有的光源通过单一路径渲染。由于移动平台性能问题,不推荐使用多个光源。默认最大值为1。如果需要打开多个光源,你必须在info.plist文件中定义如下关键词:

  1.  
    <key> cocos2d.x.3d.max_dir_light_in_shader </key>
  2.  
    <integer> 1 </integer>
  3.  
    <key> cocos2d.x.3d.max_point_light_in_shader </key>
  4.  
    <integer> 1 </integer>
  5.  
    <key> cocos2d.x.3d.max_spot_light_in_shader </key>
  6.  
    <integer> 1 </integer>

3D软件包

3D编辑器

3D编辑器是用于构建3D图形的一系列工具。既有商业的工具也有免费的工具。比较主流的编辑器有:

大部分3D编辑器保存的文件都是通用格式,以便在其他编辑器中能方便的使用,同时也便于游戏引擎以通用方式导入模型。

Cocos2d-x提供的工具

Cocos2d-x提供的工具将帮助你转换3D模型的格式,它使用转换后的格式来访问所有的3D文件。

fbx-conv命令行工具

fbx-conv允许将一个FBX文件转换为Cocos2d-x专有的格式。FBX是目前最主流的3D文件格式,所有的主流编辑器都支持这种格式。fbx-conv默认导出.c3b格式的文件。用起来很简单,只需要几个参数:

fbx-conv [-a|-b|-t] FBXFile

参数含义:

  • -?: 帮助
  • -a: 导出文本格式和二进制格式
  • -b: 导出二进制格式
  • -t: 导出文本格式

例如:

fbx-conv -a boss.FBX

关于fbx-conv需注意以下几点:

  • 模型必须有材质,且材质中至少包含一个纹理
  • 目前只支持骨骼动画
  • 目前只支持一个骨骼对象,不支持多个
  • 导出多个静态模型可以创建一个3D场景
  • 网格的顶点数或者指数的最大值是32767

3D文件格式

目前Cocos2d-x支持两种3D文件格式

  • Wavefront Object文件:.obj文件
  • Cocos2d-x 3D ad-hoc格式:c3t和c3d文件。

支持Wavefront文件格式是因为3D编辑器广泛接受这种格式,并且非常容易解析。然而,这种格式受限制并且不支持高级特征,如动画。

另一方面,c3t和c3b是Cocos2d-x的专有文件格式,接受动画、材质和其他高级3D特征。后缀"t"代表文本,后缀"b"代表二进制。开发者们需要使用c3b,因为它非常高效。但如果你想要调试文件,在git或者其他VCS中追踪更改日志,你则需要使用c3t。

进阶概念

BillBoard

以前你或许从来没听说过BillBoard(并不是指高速公路边上的广告牌)。Billboard是一个特殊的精灵,它一直正对着摄像机。旋转Camera的同时BillBoard对象也跟着旋转。使用Billboard是非常常见的渲染技术。以速降滑雪比赛为例,滑雪者路过的树木、石头或者其他物理都是Billboard对象。这就是Camera与Billboard对象之间的联系。

BillBoard.jpg

BillBoard的用法

创建Billboard对象很容易。BillBoaed继承自Sprite,所以它支持Sprite对象的大部分属性。使用如下方法可以创建Billboard对象:

auto billboard = BillBoard::create("Blue_Front1.png", BillBoard::Mode::VIEW_POINT_ORIENTED);

你还可以为摄像机的XOY平面(想象成飞机的地板)创建一个Billboard对象,只要改变BillBoard对象模式即可:

auto billboard = BillBoard::create("Blue_Front1.png", BillBoard::Mode::VIEW_PLANE_ORIENTED);

create方法看上去有些不同,因为BillBoard::Mode中多传递了一个参数。有两个BillBoard::Mode类型,VIEW_POINT_ORIENTED和VIEW_PLANE_ORIENTED

VIEW_POINT_ORIENTED代表Billboard对象面向摄像机的哪个地方,如: 9_8_1.jpg

VIEW_PLANE_ORIENTED代表Billboard对象面向摄像机XOY平面的哪个地方,如: 9_8_2.jpg

还可以给BillBoard设置属相,就像其他Node一样。属性包括但不限制于:缩放、位置、旋转。例如:

  1.  
    billboard->setScale(0.5f);
  2.  
    billboard->setPosition3D(Vec3(0.0f, 0.0f, 0.0f));
  3.  
    billboard->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
  4.  
    addChild(billboard);

PS.以上全文为Cocos引擎中文官网翻译校对,敬请勘误。转载请注明出自"Cocos引擎中文官网"。 英文原址:https://github.com/chukong/programmers-guide/blob/v3.3/chapters/9.md

分享到:
评论

相关推荐

    Cocos2d-X 3D跑酷小游戏

    这个压缩包中的“Cocos2d-X 3D跑酷小游戏”提供了游戏的完整代码示例和游戏运行的视频,对于学习Cocos2d-X以及3D游戏开发的开发者来说,是一个宝贵的资源。 Cocos2d-X基于C++,同时也支持Lua和JavaScript,使其具有...

    cocos2d-x教程

    Cocos2d-x是一个开源的游戏开发框架,广泛用于创建2D和3D游戏,教育软件,模拟器等跨平台应用程序。这个教程将深入探讨cocos2d-x的使用方法,帮助开发者掌握其核心概念和功能。 一、cocos2d-x概述 cocos2d-x是基于...

    Cocos2d-x demo程序

    Cocos2d-x 是一个广泛使用的开源游戏开发框架,它基于C++,并提供了Python、Lua等语言的绑定,使得开发者能够用多种编程语言来创建2D和3D游戏。这个" Cocos2d-x demo程序 "是作者使用Cocos2d-x编写的示例项目,用于...

    cocos2d-x-2.1.4帮助文档

    《cocos2d-x-2.1.4帮助文档》是针对游戏开发框架cocos2d-x的一个详细参考资料,该框架是用C++编写,广泛应用于2D游戏、实验性的3D游戏以及实时渲染应用程序的开发。cocos2d-x是开源的,基于cocos2d-iphone扩展而来,...

    cocos2d-x-android环境搭建文档

    【Cocos2d-x Android环境搭建】:Cocos2d-x是一个开源的游戏开发框架,它基于C++,广泛用于创建2D和3D游戏。在Android平台上开发Cocos2d-x游戏,我们需要先搭建好相应的开发环境。这个过程主要包括安装必要的软件、...

    cocos2d-x box2d 弹球

    在这个"弹球"项目中,开发者利用了Cocos2d-x的图形功能和Box2D的物理模拟能力,创建了一个类似"打砖块"(Breakout)的游戏。"Breakout"是一款经典的街机游戏,玩家通过控制一个挡板反弹球来击碎屏幕上方的砖块。 **...

    cocos2d-x3.0rc0 中文API

    cocos2d-x是一个开源的、跨平台的游戏开发框架,广泛应用于2D游戏、实验性的3D游戏以及各种交互式应用的开发。3.0版本的发布带来了许多新特性和改进,其中中文API文档的推出更是为国内开发者提供了极大的便利。本文...

    cocos2d-x创建项目配置文件

    通过理解并正确使用配置文件,开发者可以更轻松地在Cocos2d-x中创建新项目,节省时间,专注于游戏的创意实现和功能开发。同时,这也体现了Cocos2d-x致力于提供更加便捷的开发体验,降低学习曲线,提升开发者的生产力...

    cocos2d-x-3.6离线文档

    在cocos2d-x的离线文档中,类图的存在极大地帮助了开发者理解框架的架构和各个类的功能。通过类图,开发者可以直观地看到各个类的层次结构,更好地把握框架的设计思想,从而更高效地进行代码编写。 cocos2d-x 3.6...

    cocos2d-x3D扩展3DToolKitforcocos2d-x.zip

    3D ToolKit for cocos2dx 是一个简单的cocos2d-x 3D扩展,可以方便地在cocos2dx环境中创建3D图形。 基于cocos2d-x 2.2开发。 已实现功能: 1,向量和矩阵运算。 2,扩展的3D相机。(支持 透视投影 和 ...

    3d台球帧同步强联网cocos2d-x完整客户端

    在这个项目中,我们将深入探讨如何利用Cocos2d-x 3.10版本,结合Lua 5.1脚本语言,来实现一款3D台球游戏的帧同步和强联网功能。 一、Cocos2d-x 3.10版本的特点与优势 Cocos2d-x 3.10是Cocos2d-x的一个重要版本,它...

    cocos2d-x 的几个不错的代码联合起来使用

    在IT行业中,Cocos2d-x是一个非常流行的开源2D游戏开发框架,它基于C++,支持多种平台,包括iOS、Android、Windows等。本文将深入探讨如何将几个优秀的Cocos2d-x代码片段结合起来使用,以提升游戏开发效率和性能。 ...

    cocos2d-x 3d模型显示

    本主题聚焦于“cocos2d-x 3d模型显示”,这涉及到如何在Cocos2d-x环境中加载、渲染和管理3D模型。下面我们将深入探讨这一主题。 1. **3D模型格式**: - 在Cocos2d-x中,常见的3D模型文件格式包括`.obj`(Wavefront...

    cocos2d-x 2.x 图层特效Effect

    本文将深入探讨如何利用cocos2d-x的特效功能,为你的2D游戏创建出引人入胜的动画效果。 首先,我们要理解在cocos2d-x中的"图层"(Layer)概念。图层是游戏场景的基本构建块,它是一个可以包含精灵(Sprite)、文本...

    Cocos2d-x for XNA 的dll文件

    在XNA环境下,这些功能被封装在DLL中,使得开发者可以无缝地在XNA的Direct3D渲染管线和Cocos2d-x的OpenGL之间切换。 3. **物理引擎集成**:Cocos2d-x通常与Box2D或Chipmunk物理引擎配合使用,为游戏添加真实的物理...

    Cocos2d-x Android.mk文件自动修改器

    Cocos2d-x是一款流行的开源游戏开发框架,广泛用于创建2D和3D游戏。在Android平台上,构建Cocos2d-x项目时,开发者需要配置`Android.mk`文件,这是一个Makefile,用于指示Android NDK如何编译和链接C++源代码。然而...

    Cocos2d-x 3.x版本遮罩层 实现捕鱼达人金币表盘效果

    在Cocos2d-x 3.x版本中,为了实现类似捕鱼达人中的金币表盘效果,我们需要利用遮罩层(Mask Layer)技术。遮罩层是一种图形处理技术,它允许我们只显示特定区域内的图像,而隐藏其他部分。在这个场景中,我们将通过...

    cocos2d-x即时战斗类游戏《战三国》源码

    cocos2d-x即时战斗类游戏《战三国》源码 说明: 绚丽的游戏画面,酷炫的游戏场景 ☆让你体验统领千军万马的感觉 群雄逐鹿 热血三国!12位各具特色的人物和32种华丽震撼的技能带给玩家炫彩的视觉感受与轰动的战争体验!...

    Cocos2D-X2.2.3学习笔记6(UI系统)

    Cocos2D-X是一款强大的开源游戏开发框架,广泛应用于2D游戏、实验性的3D游戏以及各种跨平台的图形应用程序。在Cocos2D-X 2.2.3版本中,UI(用户界面)系统是开发者们关注的重点之一。本篇笔记将深入探讨Cocos2D-X中...

    Cocos2d-x离线文档

    4. **场景管理**:Scene类是Cocos2d-x中的核心概念,代表一个独立的游戏屏幕。Director类用于管理场景的切换,通过pushScene和replaceScene方法来实现。 5. **精灵(Sprite)**:Sprite是游戏中常用的基本元素,...

Global site tag (gtag.js) - Google Analytics