1.AutoPolygon

裁剪矩形图片的透明部分,使资源所占空间更小。

AutoPolygon 是一个工具类,它可以在程序运行时,通过跟踪关键点和三角测量,将一个矩形图像划分成一系列小三角形块。

首先将图像资源传入 AutoPolygon 进行处理,然后我们使用它生成的对象进行精灵的创建就能得到多边形精灵。

用法:

// Generate polygon info automatically.

auto polygon = AutoPolygon::generatePolygon("图片资源文件名”);

// Create a sprite with polygon info.

//参数polygon为上行所创建的多边形对象;

auto sprite = Sprite::createwith(polygon );

2.动作的倒转

倒转(Reverse) 的功能也和字面意思一样,调用 reverse() 可以让一系列动作按相反的方向执行。reverse() 不是只能简单的让一个Action 对象反向执行,还能让 SequenceSpawn 倒转。

用法:

//返回值为actionname的反转动作对象

actionname->reverse();

3.场景图(Scene Graph)

场景图(Scene Graph)是一种安排场景内对象的数据结构,它把场景内所有的 节点(Node) 都包含在一个 树(tree) 上。(场景图虽然叫做"图",但实际使用一个树结构来表示)。

听起来这好像很复杂,可能你会问,我为什么要关注这个技术细节,Cocos2d-x 值得我研究的这么深入吗?值得!这个对你真正了解渲染器是如何绘制场景的非常重要。

当你开发游戏的时候,你会添加一些节点,精灵和动画到一个场景中,你期望的是每一个添加的对象都能被正确的展示,可是如果有个对象没有被展示呢?可能你错误的把这个对象隐藏到背景中了。怎么办?别着急,这是个小问题,停下来,拿出一张纸,把场景图画出来,你肯定能很容易的发现错误。

既然场景图是一个树结构,你就能遍历它,Cocos2d-x 使用 中序遍历,先遍历左子树,然后根节点,最后是右子树。中序遍历下图的节点,能得到A, B, C, D, E, F, G, H, I 这样的序列。

初步了解了场景图,让我们看一下这个游戏场景。

分解这个场景,看一下它有哪些元素,这些最终会被渲染为一个树。

另一点要考虑的是,z-order 为负的元素,z-order 为负的节点会被放置在左子树,非负的节点会被放在右子树。实际开发的过程中,你可以按照任意顺序添加对象,他们会按照你指定的 z-order 自动排序。

4.瓦片地图

在游戏开发过程中,我们会遇到超过屏幕大小的地图,例如在即时战略游戏中,它使得玩家可以在地图中滚动游戏画面。这类游戏通常会有丰富的背景元素,如果直接使用背景图切换的方式,需要为每个不同的场景准备一张背景图,而且每个背景图都不小,这样会造成资源浪费。

瓦片地图就是为了解决这问题而产生的。一张大的世界地图或者背景图可以由几种地形来表示,每种地形对应一张小的的图片,我们称这些小的地形图片为瓦片。把这些瓦片拼接在一起,一个完整的地图就组合出来了,这就是瓦片地图的原理。

在 Cocos2d-x 中,瓦片地图实现的是 TileMap 方案,TileMap 要求每个瓦片占据地图上一个四边形或六边形的区域。把不同的瓦片拼接在一起,就可以组成完整的地图。TileMap 使用一种基于 XML 的 TMX 格式文件。

使用 TMX 文件创建一个瓦片地图:

C++
// reading in a tiled map.
auto map = TMXTiledMap::create("TileMap.tmx");
addChild(map, 0, 99); // with a tag of '99'

瓦片地图可能有许多层,通过层名获取到一个特定的层。

C++
// how to get a specific layer
auto map = TMXTiledMap::create("TileMap.tmx");
auto layer = map->getLayer("Layer0");
auto tile = layer->getTileAt(Vec2(1, 63));

每个瓦片都有独一无二的位置和 ID,这使得我们很容易选择特定的瓦片。

通过位置访问:

C++
// to obtain a specific tiles id
unsigned int gid = layer->getTileGIDAt(Vec2(0, 63));

5.粒子系统

粒子系统是指计算机图形学中模拟特定现象的技术,它在模仿自然现象、物理现象及空间扭曲上具备得天独厚的优势,能为我们实现一些真实自然而又带有随机性的效果(如爆炸、烟花、水流)提供了方便。Cocos2d-x引擎中就为我们提供了强大的粒子系统。

下面是使用粒子系统完成的两个粒子特效:

创建粒子特效的工具

尽管你能手动创建粒子特效,按照喜好确定每个属性,但是使用工具往往更方便高效。下面介绍几个第三方工具:

  1. Particle Designer:Mac 上一款非常强大的粒子特效编辑器
  2. V-play particle editor:一款跨平台的粒子特效编辑器
  3. Particle2dx:一款 Web 粒子特效编辑器,打开网页即可进行设计

使用这些工具完成粒子特效的设计,最终会导出一个 .plist 文件,Cocos2d-x 通过使用这种文件,就能把粒子特效添加到场景中,添加方法和操作一个普通的节点类型一样。

创建方法:

C++
// create by plist file
auto particleSystem = ParticleSystem::create("SpinningPeas.plist");

内置粒子特效

准备好添加粒子特效到你的游戏中了吗?是否习惯创建自定义粒子特效?不习惯也没关系,我们内置了一些粒子特效,你可以直接使用。这个列表都是:

  • ParticleFire: Point particle system. Uses Gravity mode.
  • ParticleFireworks: Point particle system. Uses Gravity mode.
  • ParticleSun: Point particle system. Uses Gravity mode.
  • ParticleGalaxy: Point particle system. Uses Gravity mode.
  • ParticleFlower: Point particle system. Uses Gravity mode.
  • ParticleMeteor: Point particle system. Uses Gravity mode.
  • ParticleSpiral: Point particle system. Uses Gravity mode.
  • ParticleExplosion: Point particle system. Uses Gravity mode.
  • ParticleSmoke: Point particle system. Uses Gravity mode.
  • ParticleSnow: Point particle system. Uses Gravity mode.
  • ParticleRain: Point particle system. Uses Gravity mode.

比如使用内置的烟火特效 ParticleFireworks

C++
auto emitter = ParticleFireworks::create();addChild(emitter, 10);

是这样的效果:

要是内置的粒子特效不是你想要的那样,也没关系,你可以直接手动设置参数!让我们拿上面的烟火特效示例,并通过手动改变属性进一步控制。

C++
auto emitter = ParticleFireworks::create();// set the duration
emitter->setDuration(ParticleSystem::DURATION_INFINITY);// radius mode
emitter->setEmitterMode(ParticleSystem::Mode::RADIUS);// radius mode: 100 pixels from center
emitter->setStartRadius(100);
emitter->setStartRadiusVar(0);
emitter->setEndRadius(ParticleSystem::START_RADIUS_EQUAL_TO_END_RADIUS);
emitter->setEndRadiusVar(0);    // not used when start == endaddChild(emitter, 10);

6.视差滚动

视差滚动是指让多层背景以不同的速度移动,从而形成的立体运动效果。比如超级马里奥游戏中,角色所在地面的移动与背景天空的移动,就是一个视差滚动。Cocos2d-x 通过ParallaxNode 对象模拟视差滚动。可以通过序列控制移动,也可以通过监听鼠标,触摸,加速度计,键盘等事件控制移动。ParallaxNode 对象比常规节点对象复杂一些,因为为了呈现不同的移动速度,需要多个子节点。它类似Menu 像一个容器,本身不移动,移动的是被添加进入其中的不同子节点。ParallaxNode 的创建:

C++
// create ParallaxNode
auto paraNode = ParallaxNode::create();

添加多个节点对象:

C++
// create ParallaxNode
auto paraNode = ParallaxNode::create();// background image is moved at a ratio of 0.4x, 0.5y
paraNode->addChild(background, -1, Vec2(0.4f,0.5f), Vec2::ZERO);// tiles are moved at a ratio of 2.2x, 1.0y
paraNode->addChild(middle_layer, 1, Vec2(2.2f,1.0f), Vec2(0,-200) );// top image is moved at a ratio of 3.0x, 2.5y
paraNode->addChild(top layer, 2, Vec2(3.0f,2.5f), Vec2(200,800) );

需要注意的是,被添加的每个 Node 对象被赋予了一个唯一的 z-order 顺序,以便他们堆叠在彼此之上。另外要注意addChild() 调用中两个 Vec2 参数,第一个决定这个子节点的移动速度与父节点移动速度的比率,第二个是相对父节点ParallaxNode 的偏移量。

7.键盘事件

对于桌面游戏,一般需要通过键盘做一些游戏内的控制,这时你就需要监听键盘事件。Cocos2d-x 支持键盘事件,就像上节介绍的触摸事件一样。

创建键盘事件监听器:

C++
// creating a keyboard event listener
auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);// Implementation of the keyboard event callback function prototype
void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
{log("Key with keycode %d pressed", keyCode);
}void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
{log("Key with keycode %d released", keyCode);
}

可以看到,在使用键盘事件监听器时,可以监听两种不同的事件,每一个事件都有自己的触发时机。

两种事件及触发时机:

  • onKeyPressed 按键被按下时
  • onKeyReleased 按下状态的按键被放开时

8.加速度传感器事件

现在一些移动设备配备有加速度传感器,我们可以通过监听它的事件获取各方向的加速度。

可以设想要完成一个游戏情景:通过来回移动手机,平衡小球在手机中的位置。这种场景的完成,就需要监听加速度传感器事件。

使用加速度传感器,需要先启用

C++
Device::setAccelerometerEnabled(true);

创建加速度传感器监听器:

C++
// creating an accelerometer event
auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(
AccelerometerTest::onAcceleration, this));_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);// Implementation of the accelerometer callback function prototype
void AccelerometerTest::onAcceleration(Acceleration* acc, Event* event)
{//  Processing logic here
}

9.鼠标事件

就像前几节介绍的那样,Cocos2d-x 支持响应鼠标事件

创建鼠标事件监听器:

C++
_mouseListener = EventListenerMouse::create();
_mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
_mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
_mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);
_mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);void MouseTest::onMouseDown(Event *event)
{// to illustrate the event....EventMouse* e = (EventMouse*)event;string str = "Mouse Down detected, Key: ";str += tostr(e->getMouseButton());
}void MouseTest::onMouseUp(Event *event)
{// to illustrate the event....EventMouse* e = (EventMouse*)event;string str = "Mouse Up detected, Key: ";str += tostr(e->getMouseButton());
}void MouseTest::onMouseMove(Event *event)
{// to illustrate the event....EventMouse* e = (EventMouse*)event;string str = "MousePosition X:";str = str + tostr(e->getCursorX()) + " Y:" + tostr(e->getCursorY());
}void MouseTest::onMouseScroll(Event *event)
{// to illustrate the event....EventMouse* e = (EventMouse*)event;string str = "Mouse Scroll detected, X: ";str = str + tostr(e->getScrollX()) + " Y: " + tostr(e->getScrollY());
}

10.是否需要使用物理引擎

当你的需求很简单时,就不要使用物理引擎。比如只需要确定两个对象是否有碰撞,结合使用节点对象的 update 函数和 Rect 对象的 containsPoint()intersectsRect() 方法可能就足够了。例如:
C++
void update(float dt)
{auto p = touch->getLocation();auto rect = this->getBoundingBox();if(rect.containsPoint(p)){// do something, intersection}
}


这种检查交集以确定两个对象是否有碰撞的方法,只能解决非常简单的需求,无法扩展。比如你要开发一个游戏,一个场景有 100 个精灵对象,需要判断它们互相是否有碰撞,如果使用这种方式那将非常复杂,同时性能消耗还会严重影响 CPU 的使用率和游戏运行的帧率,这游戏根本没法玩。这个时候就需要物理引擎了,在模拟物理情景上,物理引擎的扩展性好,性能的消耗也低。像刚才提到的那个情景,使用物理引擎就能很好的解决。初次了解物理引擎的话,肯定会觉得很陌生,我们来看一个简单的例子,通过例子来介绍术语,或许会容易接受一些。
C++
// create a static PhysicsBody
auto physicsBody = PhysicsBody::createBox(Size(65.0f , 81.0f ), PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setDynamic(false);// create a sprite
auto sprite = Sprite::create("whiteSprite.png");
sprite->setPosition(Vec2(400, 400));// sprite will use physicsBody
sprite->addComponent(physicsBody);//add contact event listener
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);


虽然上面这个例子已经很简单了,但你可能还是觉得它复杂得有点吓人?别害怕,仔细的分析一下,就会发现也没那么复杂。代码流程:
  1. PhysicsBody 对象创建
  2. Sprite 对象创建
  3. PhysicsBody 对象以组件的形式被添加到 Sprite 对象
  4. 创建监听器以响应 onContactBegin() 事件
保持耐心,一旦我们一步一步的去分析,慢慢的就能理解这个过程。

学习小计(部分摘自cocos官方文档)1相关推荐

  1. 学习小计(部分摘自cocos官方文档) 2

     11.碰撞 你是否看到过车祸?是否跟什么物体相撞过?就像车的相撞一样,刚体对象也可以互相碰撞,当它们互相接触的时候,就认为发生了碰撞.当碰撞发生时,会触发一系列事件,它可以被完全忽略. 碰撞筛选 ...

  2. 微信小程序(note1:官方文档)

    官方文档 关于微信小程序这块儿,主要练习怎么查看文档,因为微信开发文档特别全面,没有必要再额外写什么笔记. 但是对小程序开发文档的熟练度是非常重要的,所以此系列笔记,着重于常用的组件.接口- 微信小程 ...

  3. tensorflow学习笔记十7:tensorflow官方文档学习 How to Retrain Inception's Final Layer for New Categories

    现代物体识别模型有数以百万计的参数,可能需要数周才能完全训练.学习迁移是一个捷径,很多这样的工作,以充分的训练模式的一组类ImageNet技术,并从现有的权重进行新课.在这个例子中,我们将从头再训练最 ...

  4. YII2 路由问题-摘自yii2官方文档

    路由 当入口脚本在调用 run() 方法时,它进行的第一个操作就是解析输入的请求,然后实例化对应的控制器动作处理这个请求. 该过程就被称为引导路由(routing). 路由相反的操作会将给定的路由和参 ...

  5. UE4学习(一)C++编程官方文档解读

    文档地址:https://docs.unrealengine.com/zh-CN/Programming/Introduction/index.html 文档详细介绍了C++编程的基础,一些宏和常用变 ...

  6. 微信小程序学习记录【1】【项目结构构成、官方文档构成、基本配置】

    微信小程序学习记录[1][项目结构构成.基本配置]文章目录 项目结构构成 官方文档结构 基本配置 1. 小程序配置 1.1 app.json 1.2 page(页面名).json 1.3 sitema ...

  7. 微信小程序入门:初步了解官方文档(循环、视图容器、icon、image)

    今天是正式学习微信小程序的第一天,学习微信小程序先从了解官方文档开始吧. 这一节开始学习微信小程序官方文档中的for循环.视图容器.icon.image等. 打开index文件夹下的index.wxm ...

  8. mysql中括号_手把手教你看MySQL官方文档

    前言: 在学习和使用MySQL的过程中,难免会遇到各种问题.不知道当你遇到相关问题时会怎么做,我在工作或写文章的过程中,遇到不懂或需要求证的问题时通常会去查阅官方文档.慢慢的,阅读文档也有了一些经验, ...

  9. 如何全文搜索oracle官方文档

    如何全文搜索oracle官方文档 [技巧]如何全文搜索oracle官方文档 一.1  BLOG文档结构图 一.2  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它 ...

最新文章

  1. Python 图像处理简介——色彩阴影调整
  2. php-fpm 启动参数及重要配置详解
  3. XtraBackup出现 Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
  4. RabbitMQ创建远程连接用户
  5. Android动画之Tween动画实战
  6. 【page-monitor 前端自动化 上篇】初步调研
  7. 缓存nginx服务器的静态文件
  8. list可以存放python中任意类型的数据_Python中常见的数据类型小结
  9. ROS学习笔记-ROS语音识别与语音输出[1]
  10. python交互模式设置及VIM的tab补齐
  11. 单片机开发与Linux开发有何不同?
  12. Qt通过ODBC读取excel文件
  13. tableau获取筛选器值_认识Tableau中的筛选器
  14. Java笔记-Java端口扫描功能(含TCP包分析以及原理)
  15. DSB2017第一名代码尝试运行(记录自用)(一)
  16. Win7下 OpenCV+Qt开发环境搭建
  17. 简用计算机,你真的会使用“计算器”吗?
  18. OpenCV morphologyEx、erode、dilate、getStructuringElement (形态学算子)
  19. 关闭此标签页 关闭所有标签页easyUI
  20. 2012.4.19总结(一)

热门文章

  1. Google Earth Engine(GEE)——土地分类/覆盖案例分析含各类土地面积统计和精度评定(印度班加罗尔为例)
  2. 2021小红书国际妇女节营销报告
  3. OSChina 娱乐弹弹弹——程序猿其实很好找女朋友!
  4. [原创]ExtAspNet秘密花园(二) mdash; 一切从头开始
  5. 【TCP/IP网络协议】(五)传输层UDP协议
  6. dubbo-monitor启动异常之Native memory allocation (mmap) failed to map 1879048192 bytes for committing rese
  7. k8s创建pod资源失败OCI runtime create failed systemd cgroup flag passed, but systemd support for managing c
  8. python调用通达信函数_mootdx: 通达信数据读取 pytdx 的一个简便使用封装
  9. mmc/eMMC/SD-card/SPI/SDIO
  10. ELK收集nginx日志并展示来源IP城市分布图