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对象:

auto sprite = Sprite3D::create("boss.c3b"); //c3b file, created with the FBX-converter
sprite->setScale(5.f); //sets the object scale in float
sprite->setPosition(Vec2(200,200)); //sets sprite position
scene->addChild(sprite,1); //adds sprite to scene, z-index: 1

.c3b3D文件可以用FBX-converter工具来创建

现在,让我们来循环旋转模型。为此,我们将创建一个操作并运行它:

//rotate around the X axis
auto rotation = RotateBy::create(15, Vec3(0, 360, 0));
//our sprite object runs the action
sprite->runAction(RepeatForever::create(rotation));

要在Sprite或Sprite3D上设置定位点,请使用:

sprite->setAnchorPoint(Point(0.0f,0.0f));

将三维模型附加到Sprite3D对象

请记住,三维模型是网格的集合。可以将三维模型附加到其他三维模型以创建丰富的效果。如添加武器到主角上,为了做到这一点,你需要找到武器将被添加的附着点。可以调用getAttachNode(attachment_point_name)函数来找到。 然后我们用addChild()将新模型作为子模型添加到附件点 。

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

交换三维模型

当做3D开发时,你可能要对你的模型做些动态改变 。这种改变可能是换装、 视觉线索 、通知用户关于模型的状态变化。 如果三维模型由网格组成,则可以使用getMeshByIndex()getMeshByName()访问网格数据。 . 使用这些功能,可以实现像用武器或衣服交换角色一样的效果。

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);

Animation动画

创建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));

多动画
同时运行多个动画。

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秒,第二个在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,可以用如下代码创建:

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, 0), Vec3(0, 1, 0));addChild(camera); //add camera to the scene

创建正交照相机
默认的Camera是透视照相机,如果要创建正交照相机,可以用如下代码来创建:

Camera::createOrthographic();

如:

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

从相机中隐藏对象
有时,我们并不想在照相机里显示所有对象。从一个照相机里隐藏一个对象其实也很简单,通过在Node(节点)上调用setCameraMask(CameraFlag)和在Camera上调用setCameraFlag(CameraFlag)即可:

//Camera
camera->setCameraFlag(CameraFlag::USER1);//Node
node->setCameraMask(CameraFlag::USER1);

Cubemap Texture立方纹理

立方体贴图纹理是六个单独的正方形纹理的集合,这些纹理放置在虚拟立方体的面上。它们通常用于在对象上显示无限远的反射,类似于“天空盒”在背景中显示遥远景物的方式。展开的立方体映射的外观 :

Cocos2d-x创建立方纹理的方法:

// create a textureCube object with six texture assets
auto textureCube = TextureCube::create("skybox/left.jpg",  "skybox/right.jpg", "skybox/top.jpg", "skybox/bottom.jpg", "skybox/front.jpg", "skybox/back.jpg");// set cube map texture parameters
Texture2D::TexParams tRepeatParams;
tRepeatParams.magFilter = GL_NEAREST;
tRepeatParams.minFilter = GL_NEAREST;
tRepeatParams.wrapS = GL_MIRRORED_REPEAT;
tRepeatParams.wrapT = GL_MIRRORED_REPEAT;
textureCube->setTexParameters(tRepeatParams);// create and set our custom shader
auto shader = GLProgram::createWithFilenames("cube_map.vert", "cube_map.frag");
auto _state = GLProgramState::create(shader);// bind cube map texture to uniform
state->setUniformTexture("u_cubeTex", textureCube);

Skybox

Skybox是你整个场景的包装,它显示了你的几何之外的世界。你可以用一个天空盒来模拟无限的天空、山脉和其他现象。 创建Skybox:

// create a Skybox object
auto box = Skybox::create();// set textureCube for Skybox
box->setTexture(_textureCube);// attached to scene
_scene->addChild(box);

Light光线

光线对于营造游戏的气氛和氛围非常重要。目前支持4种照明技术。

  • Ambient Light(环绕光): AmbientLight对象将均匀地为场景中的所有对象应用灯光。效果就像办公室里的照明。灯光在头顶,当你看到办公室周围的物体时,你会看到它们在同一个灯光下。
auto light = AmbientLight::create (Color3B::RED);
addChild(light);
  • Directional Light(平行光、定向光): 平行光通常用于模拟光源,如阳光。当使用方向光时,请记住它的密度是相同的,不管你和它的关系是什么。当你直视太阳时,它是一种强烈的光,即使你朝任何方向移动几步 。
auto light = DirectionLight::create(Vec3(-1.0f, -1.0f, 0.0f), Color3B::RED);
addChild(light);
  • Point Light点光源:点光源通常用于模拟灯泡、灯或火炬的效果。 点光源的方向是 从发光位置到点光源 。离光源近则亮,远则暗。
auto light = PointLight::create(Vec3(0.0f, 0.0f, 0.0f), Color3B::RED, 10000.0f);
addChild(light);
  • Spot Light聚光源:聚光源通常用于模拟手电筒。:
auto spotLight = SpotLight::create(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
Color3B::RED, 0.0, 0.5, 10000.0f) ;
addChild(spotLight);

遮光

在节点上使用照明遮罩仅对其应用特定的光源。例如,如果场景中有多个灯光,则节点只能由其中一个灯光而不是全部三个灯光照亮。可以使用setLightFlag(LightFlag)控制灯光影响哪些节点对象。需要注意的是,所有光源都是在一个过程中渲染的。由于移动平台性能问题,不建议使用多个光源。默认最大值为1。如果要打开多个光源,必须在info.plist中定义以下键:

<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>

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::CrackFixedType::SKIRT: 将在块的每个边上生成四个类似裙子的网格。
Terrain::CrackFixedType::INCREASE_LOWER: 将动态调整每个块索引以无缝连接它们。

创建Terrain地形
以下代码片段创建一个玩家并将其放置在地形图上:

player->setScale(0.08);
player->setPositionY(terrain->getHeight(player->getPositionX(),player->getPositionZ()));

创建所有DetailMap对象,最多4个。我们需要将DetailMap对象传递给Terrain::DetailMap结构体:

Terrain::DetailMap r("dirt.dds");
Terrain::DetailMap g("grass.dds");
Terrain::DetailMap b("road.dds");
Terrain::DetailMap a("greenSkin.jpg");

用DetailMap对象创建TerrainData变量,并指定高度图文件路径和字母图文件路径:

Terrain::TerrainData data("chapter9/heightmap16.jpg","TerrainTest/alphamap.png", r, g, b, a);

传递TerrainData对象给Terrain::create,最后一个参数决定LOD政策:

_terrain = Terrain::create(data, Terrain::CrackFixedType::SKIRT);

如果你设置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将会动态调整每个块索引以无缝连接它们。

Cocos2d-x之3D相关推荐

  1. cocos2D插件转3D插件

    cocos2D插件转3D插件 'use strict';/*** 3d插件api映射,兼容2d插件* */let fs = require("fs");let path = req ...

  2. 如何在COCOS2D中绘制3d椭圆柱?

    将以下代码添加到CCActionGrid3D.h class CC_DLL CCEllipse3D : public CCGrid3DAction { public: /** initializes ...

  3. Cocos2D研究院之精灵与动画

    转载自雨松MOMO程序研究院本文链接地址:Cocos2D研究院之精灵与动画(六) 通过对导演.场景.层和节点的剖析,现在我们已经可以写出一个完整的游戏体系了,在实际应用中,场景一般都是作为游戏的关卡, ...

  4. Cocos2d-x 3D模型渲染

    Cocos2d-x 3D模型渲染 声明:本文使用的是cocos2d-x-3.17的代码 文章中的提到的测试代码下载地址https://gitee.com/Kyle12/Cocos2dRenderStu ...

  5. cocos3D 教程

    iPhone Cocos3D 教程 介绍: Cocos3d框架是iOS平台高度提炼的3D应用开发框架. Cocos3d是cocos2d的扩展集,cocos2d深入人心,广泛使用在iOS 2d游戏开发中 ...

  6. 游戏策划概述(二)——设计

    (标注: 本博文的所有内容,是根据阅读了<游戏架构设计与策划基础>这本书, 想把自己看的一些觉得重要的东西和感悟记下来,不多说了,下面开始正题.) 想要进行游戏设计,就需要有很好的创意来源 ...

  7. 主流游戏引擎的详细比较和选择分析 - 优选澎湃动力 - 天天飞车游戏引擎选型

    转自:http://gad.qq.com/college/articledetail?cid=486 一.引擎史话 游戏引擎已经成为目前游戏开发必不可少的工具,它所提供的便利性和稳定性在大大降低了游戏 ...

  8. cocos 射线检测 3D物体 (Sprite3D点击)

    看了很多朋友问怎么用一个3D物体做一个按钮,而且网上好像还真比较难找到答案, 今天翻了一下cocos源码发现Ray 已经封装了intersects函数,那么剩下的工作其实很简单了, 从屏幕的一个poi ...

  9. Cocos2d:使用 CCCamera 做滚动效果 (Four Ways of Scrolling with Cocos2D)

    原版的:http://www.koboldtouch.com/display/IDCAR/Four+Ways+of+Scrolling+with+Cocos2D There are two class ...

  10. 2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效...

     1 类图组织 2 实例 CCSprite * spr = CCSprite::create("HelloWorld.png"); spr->setPosition(cc ...

最新文章

  1. 玩玩TCPCOPY+ intercept+mysql-replay-module(未成功)
  2. Android--PullToRefreshListView 的简单使用
  3. Fedora 32发布时间表(Fedora 32 Schedule)
  4. WCF学习之旅—请求与答复模式和单向模式(十九)
  5. Windows在当前目录快速打开cmd的方法
  6. 码农与UI沟通的日常
  7. Arquillian变色龙。 简化您的Arquillian测试
  8. Spring Boot笔记-JPA分页(后端分页)
  9. unity android屏幕自适应,Android应用开发之unity打开移动摄像头,并自适应屏幕显示摄像头数据。兼容android和ios...
  10. 检測磁盘驱动的健康程度SMART
  11. 负载均衡故障排错指南 (3)
  12. vs2012安装VA插件
  13. 实验9(延伸) 多元函数微分法及其应用
  14. 获取钉钉考勤机的打卡记录并且解析
  15. 访客一体机六大鸡肋功能
  16. nodejs--process
  17. windows 操作系统安全运维所考虑的安全基线内容
  18. 使用弗洛伊德算法(Floyd-Warshall)找到所有对最短路径长度
  19. 字体反爬之猫眼票房爬虫python
  20. 时间格式24小时制和12小时制

热门文章

  1. 1032:Parliament
  2. 史诗级计算机字符编码知识分享,万字长文,一文即懂!
  3. 网站空间配置和域名解析怎么选择
  4. 一杯奶茶的数字化之路
  5. 【转】python问题 Traceback (most recent call last)
  6. 快速傅里叶变换——FFT
  7. 通达信接口怎么样抓取股票实时数据?
  8. 【数据分析可视化】通过apply进行数据预处理
  9. Windows 10 / 11 环境变量 (用户变量与系统变量)
  10. 【React】从0开始的React笔记