Cocos2d-x中的基础概念

Cocos2d-x中的基础概念

尊重原创:http://cn.cocos2d-x.org/tutorial/show?id=1926

在你阅读本章节之前你可能知道一些关于Cocos2d-x的知识,但是你可能想知道更多关于如何使用Cocos2d-x来制作出自己梦想的游戏。

没问题,让我们从现在开始。

Cocos2d-x是一个跨平台的游戏引擎。什么是游戏引擎?现在不要被这个问题吓到!

一个游戏引擎就是一个可以提供大多游戏常用功能的软件作品。你之前也许听到过将它称之为API或者框架。但在本书中我们会使用游戏引擎这个比较正式的术语。

游戏引擎包括了许多组件,将它们组合使用有利于游戏性能提升和开发周期的缩短。

通常游戏引擎中都包含这些组件,比如:渲染器,2d/3d图形,碰撞检测,物理引擎,声音,控制器,动画等。

游戏引擎通常支持多平台,所以会比较容易对游戏进行移植,将游戏移部署到其它平台只需要一小部分的工作量。

由于Cocos2d-x是一个游戏引擎,它提供了一个简化的API用来开发跨平台的移动和桌面游戏。

通过内置的封装且易于使用的API,你可以专注于开发游戏,不用去关心内部技术的实现。

Cocos2d-x将会尽可能的为游戏开发者提供更大的自由空间。

Cocos2d-x提供了Scene, Transition, Sprite, Menu, Sprite3D, Audio等许多对象。你创建游戏所需要的内容都在这了。

主要组件

看起来好像很复杂,但是开始使用Cocos2d-x是很简单的。

在我们继续进行深入之前,需要理解一些Cocos2d-x中的概念。

Cocos2d-x的核心类为 Scene, Node, Sprite, MenuAction对象。仔细观察你玩过的游戏你就会发现所有这些部分!

让我们来看一个例子。这看起来像一个很流行的游戏,你也许玩过:

你能找出这些部分吗?让我们来分析一下:

也许你对自己的游戏有一个大概的描绘?和上面的例子对比一下你的游戏中都包括了哪部分。

导演类

Cocos2d-x使用Director(导演)的概念。是的,就像拍电影一样!

Director类控制着游戏整体并通知游戏接下来需要做什么。

把你自己当成影片的监制人,你肯定会通知导演(Director)该如何做!

Director导演的一个通常作用是控制Scene 切换和切换效果。

导演(Director)是一个共享的单例对象,你可以从代码的任何地方调用。

这里是一个典型游戏的流程图。导演 (Director)通过这个流程图来对游戏进行调渡并决定了游戏的标准:

你就是游戏的导演。你决定了游戏中将会发生什么,什么时候发生,如何发生。

这些你都要负责!

场景

游戏中你可能需要一个主菜单,几个关卡和一个结束场景。

你该如何将这些内容单独的分开来呢?是的,这就需要Scene

回想一下你喜欢的电影,你会发现它很显示的划分出了一些场景,或者单独的故事剧情。

如果我们按照这种思路来处理游戏,不管游戏有多么简单但我们应该想出至少有几个场景。

看下这张图片:

这是一个独立的主界面场景Scene。这个场景是将组件组合在一起而形成一个最终的场景。

场景都由Renderer进行绘制。Renderer可以用来绘制精灵或者其它对象到场景中。为了更好的理解这点我们需要了解一些关于_Scene Graph_的知识。

场景图

_scene graph_是一个用来存储场景图形的数据结构。

_scene graph_由树节点构成。(它虽然叫screne graph,但它实际上是用树形结构来存储)。

这看起来好像很复杂。我敢肯定你会问为什么我们要了解这些底层技术,这不是和cocos2d-x的原则相违背吗?实际上,明白场景是如何来进行绘制的这一点显得很有必要。当你在游戏中添加节点,精灵或者动画的时候,你肯定希望最终的表现结果是你所预期的。但如果没有达到预期效果呢?

如果你添加的精灵对象在背景层但你希望它们在最前面该怎么办?回到上一步通过将场景放到一个背景上然后在运行,我敢保证你很快会发现自己所犯的错误。

由于_Scene Graph_是树形结构;你可以对它进行遍历。Cocos2d-x使用了_in-order walk_算法。_in-order walk算法的流程如图所示,从根节点开始,然后到右边的树。由于右边的节点是最后绘制的,所以它会首先被显示到场景中。

_scene graph_很容易理解,让我们来对图中所示的场景进行分解:

将上面的场景表示为一个树形,可以简化为如下:

另一个需要注意的地方是,_z-order_Z轴为负数的元素会出现在树的左侧,而_z-order_Z轴为正数的会出现在树的右侧。

当在场景中添加结点的时候需要注意这一点。当然你可以在任意的地方添加节点元素它们会被按钮Z轴的大小自动排序。

在这个概念的基础上,我们可以把Scene的视为一个Node 对象。

先暂时不看上一个场景,来看一下_scene graph_如何利用_z轴_来布局Scene

图中左边的场景是由许多节点对象组成的,但每个对象都处在不同的_z-order_Z轴上。

在Cocos2d-x中,可以通过API中的addChild()方法来创建_scene graph_场景。


1

// Adds a child with the z-order of -2, that means // it goes to the "left" side of the tree (because it is negative) scene->addChild(title_node, -2); // When you don‘t specify the z-order, it will use 0 scene->addChild(label_node);// Adds a child with the z-order of 1, that means // it goes to the "right" side of the tree (because it is positive) scene->addChild(sprite_node, 1);

精灵

所有的游戏都有_Sprites_精灵,你可能知道或者不知道它们是什么。精灵就是游戏中在场景里进行移动的对象。

你可以操纵它们。精灵可能是游戏中最主要的角色。我知道你在想什么-难道每一个图形对象都是精灵Sprite吗?

当然不是!为什么?当你操纵一个精灵的时候,它就是一个精灵。如果你不对它进行操作,那它就是一个节点Node

看一下图片,我们来说明一下什么是精灵,什么是节点:

精灵是每一个游戏的关键所在。编写一个游戏,你可能需要使用一些带有共同特性的图像。这就是一个Sprite精灵。

_Sprites_精灵很容易创建,它具有很多属性,比如:坐标position,翻转rotation,缩放scale,透明度opacity,颜色color等。


1

// This is how to create an sprite auto mySprite = Sprite::create("mysprite.png"); // this is how to change the properties of the sprite mySprite->setPosition(Vec2(500, 0));mySprite->setRotation(40); mySprite->setScale(2.0); // sets scale X and Y uniformly mySprite->setAchorVec2(0, 0);

下面我们来解释每个属性的作用,通过本章的示例代码来思考下面的截图:

通过代码 mySprite->setPosition(Vec2(500, 0));将坐标进行重新设置,如图:

看一下发生了什么。Sprite的坐标从它原有的坐标被移动到了我们设定的新坐标。

通过代码mySprite->setRotation(40);对精灵的翻转进行设定,如图:

看一下发生了什么。Sprite精灵被翻转了我们所设定的角度。

通过代码mySprite->setScale(2.0);将精灵进行缩放,如图:

同样地,我们可以发现精灵的大小被改变了。

最后,所有的节点Node对象(注意Sprite精灵类是Node节点类的子类)都有一个称为锚点的值。我们之前还没有提过这个概念,现在时机正好。你可以将锚点想象为在对精灵进行坐标点设定的时候精灵所自身使用的坐标点。

通过代码mySprite->setAchorVec2(0, 0);将游戏中的精灵锚点设定为(0,0)坐标,那么所有使用代码setPosition()进行坐标设定的精灵都会以自身的左下角来进行对齐。让我们来试一下:

注意观察每个图像中的红点。这个红点就是精灵的锚点位置!

你会发现锚点对节点来说是非常有用的。你甚至可以通过调整精灵的锚点来模拟动态效果。

现在我们已经可以很好地使用精灵了。那么该如何让这些精灵按照一定的时间间隔自动的进行播放呢?继续向下看。

动作

创建Scene场景,添加Sprite精灵对象到屏幕上只是其中一部分。

游戏之所以称为游戏就是我们需要让精灵运动起来!Action动作游戏中的一部分。_Actions_动作类可以让Node节点对象按时间进行运动。

希望将一个Sprite精灵从一个坐标点移动到另一个坐标并在结束时调用回调函数?没有问题!

你可以创建一个Actions动作序列Sequence并且按顺序播放。你可以通过改变Node节点属,坐标,角度,缩放。比如说这些动作:MoveByRotate, Scale。所有的游戏都使用动作类Actions

查看本章的示例代码,下面就是_Actions_的演示:

5秒过后,精灵会移动到新的坐标点:

_Actions_很容易创建使用:


1

auto mySprite = Sprite::create("Blue_Front1.png"); // Move a sprite 50 pixels to the right, and 10 pixels to the top over 2 seconds. auto moveBy = MoveBy::create(2, Vec2(50,10));mySprite->runAction(moveBy); // Move a sprite to a specific location over 2 seconds. auto moveTo = MoveTo::create(2, Vec2(50,10));mySprite->runAction(moveTo);

序列和Spawns

让精灵在屏幕中进行移动就是我们想要的最终结果了吗?当然不是。可不可以运行多个动作呢?是的,没问题,Cocos2d-x通过几个方式来支持这种操作。

就如同它的名字,一个序列Sequence就是多个动作按钮一定顺序进行排列。需要按反方向来播放序列动作?也没问题,Cocos2d-x也支持这个操作。

看一下面的例子,通过序列Sequence逐步移动一个精灵Sprite:

这个Sequence很容易创建:


1

auto mySprite = Node::create()// move to point 50,10 over 2 seconds auto moveTo1 = MoveTo::create(2, Vec2(50,10)); // move from current postion by 100,10 over 2 seconds auto moveBy1 = MoveBy::create(2, Vec2(100,10)); // move to point 150,10 over 2 seconds auto moveTo2 = MoveTo::create(2, Vec2(150,10));// create a delay auto delay = DelayTime::create(1); mySprite->runAction(Sequence::create(moveTo1, delay, moveBy1, delay->clone(), moveTo2, nullptr));

本例中按顺序播放序列中的每一个动作,如何同步一起运行这些动作?Cocos2d-x也支持这个操作,它称做SpawnSpawn会在同一时间播放所有指定的动作。有一些可能比别的稍长一些,所以出现这种情况动作的播放不会在同一时间完成。


1

auto myNode = Node::create()auto moveTo1 = MoveTo::create(2, Vec2(50,10)); auto moveBy1 = MoveTo::create(2, Vec2(100,10)); auto moveTo2 = MoveTo::create(2, Vec2(150,10)); myNode->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));

为什么要使用Spawn呢?有什么理由吗?当然!当游戏的主角获得能力提升时要播放多个动作的时候。当BOSS战的最后阶段需要同时播放多个动作来终结的时候。

父类和子类之间的继承关系

Cocos2d-x使用Parent and Child继承。也就是说父类中的属性也适用于他们的子类。考虑一个Sprite对象和它的子类对象Sprite

当改变父类中的精灵角度时,子类的角度也会随之进行变化:


1

auto myNode = Node::create();// rotating by settingmyNode->setRotation(50);

不光是角度,如果你将父类进行缩放,那么子类的精灵也会跟着缩放:


1

auto myNode = Node::create();// scaling by setting myNode->setScale(2.0); // scales uniformly by 2.0

总结

我们已经介绍了一些Cocos2d-x中的概念。放轻松呢,不要太担心。按照自己的想法一步一个脚印的来。Cocos2d-x和编程并不是一种可以通过熬夜就可以学会的技能。这些都需要练习和思考。

时间: 2024-10-04 10:20:33

Cocos2d-x中的基础概念的相关文章

JavaScript随笔记(一)基础概念以及变量类型

一.JavaScript中的基础概念 1.defer属性 一般我们在引用外部js文件的时候往往是将引用文件的位置放在标签当中,比如那么在标签中引入多个js文件时,浏览器会按照引入顺序加载执行这些引入的js文件,如果加载执行的这些js文件的时间比较长,那么页面就会处在等待期间.在下载引入的js文件时,现在的浏览器大多都是会并行下载的,不会去单线程的下载,这样提高了效率,但仍然会阻塞一些其他资源的下载比如说图片的下载,这样就因为js的下载执行而阻塞了UI渲染,会在页面上形成空白页面,这时我们可以有多

Lua语言基础汇总(10) -- Lua中的环境概念

前言 Lua将其所有的全局变量保存在一个常规的table中,这个table称为“环境”.这种组织结构的优点在于,其一,不需要再为全局变量创造一种新的数据结构,因此简化了Lua的内部实现:另一个优点是,可以像其他table一样操作这个table.为了便于实施这种操作,Lua将环境table自身保存在一个全局变量_G中.例如,我们可以使用以下代码打印当前环境中所有全局变量的名称. 1 for n in pairs(_G) do print(n) end 在你的电脑上运行一下以上代码,看看结果. 全局

PowerShell_零基础自学课程_5_自定义PowerShell环境及Powershell中的基本概念

PowerShell_零基础自学课程_5_自定义PowerShell环境及Powershell中的基本概念 据我个人所知,windows下的cmd shell除了能够通过修改系统参数来对其中的环境变量进行改变外,其环境的可自定义性相对来说很困难,而在Linux环境中,可以通过修改/etc目录下的某些配置文件来达到配置shell环境的目的.也许这也是某些人诟病cmd shell功能不强的原因之一. 而目前这种状况在windows powershell中得到了改善,可以说PS中提供的自定义环境的功能

【Cocos2d入门教程二】Cocos2d-x基础概念

上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: 环境设定(帧率 初始化openGl和渲染器) 场景管理 执行主循环 游戏就是个死循环 不断不断的渲染  就跟视频没两样 一帧一帧的绘制出来  话说提一下一帧为1/60秒  也就是说coco里一秒渲染60次 导演的管理:   计时器  事件管理器  动作管理器 导演继承于REF  一个单例类 获得导演类Director实例语句 au

关系型数据库常用基础概念知识归纳

声明:我的文章都是只挑主要的写,次要细节太多,归纳就没意义了,同时归纳主要是给自己看的, 而且基本都是凭自己的一些记忆和理解即时写的.不一定对和全(但大多是一些需要理解的概念),请各位看管见谅! 数据库设计篇 1.范式 A.1范式,原子性,即列不可分 B.2范式,完全依赖,即有个主键唯一区分 C.3范式,不能传递依赖,即表中不能还有其他表的非主键信息 2.模型 A.概念模型,即ER图等 B.逻辑模型,即建逻辑表 C.物理模型,即生成物理表 事务 1.四大特性, A.原子,要么..要么.. B.隔

分布式学习——基础概念篇

概述 最近这段时间一直在看分布式有关的东西,但是关于分布式自己还是不能很好的理解,所以本文对分布式基础概念进行下学习. 分布式处理 首先先了解一下分布式处理,分布式处理和集中式处理正好是相反的的体系架构,集中传输集中到式处理顾名思义就是将所有的信息都一个统一的信息中心进行处理:分布式处理就是将不同地点的,或具有不同功能的,或拥有不同数据的多台计算机利用通信网络连接起来,让各个计算机各自承担同一个工作任务的不同部分,在控制中心的管理下,同时运行,共同完成同一个工作任务. 提到分布式处理就不能不提到

js基础--javascript基础概念之语法

掌握一门语言 必须先掌握它的语法! javascript 的语法和C.Java.Perl 的语法有些相似.但是比它们更加宽松. javascript 中的一切都是严格区分大小写的.例如变量: demo 和 Demo 两个变量是完全不同的. javascript 标示符,所谓标示符 是指 变量.函数.属性 的名字或函数的参数.标示符的格式是按照以下规则组合的一个或多个字符. 1.第一个字符必须是字母,下划线,或 $ 符号. 2.其他字符可以是字母.下划线.$ . 或数字. 注意 不能把关键字 保留

js基础--javascript基础概念之数组(二)

js基础--javascript基础概念之数组 数组栈方法 数组可以像栈一样.栈是一种先进后出的数据结构,最先添加的数据最后一个出来.栈方法添加数据也称为 推入  移除数据称为 弹出. js为数值栈方法提供了 push()   和  pop() ;  两个方法. push() push() 方法接受参数就是你要添加进入到数组的值.push()  方法会将他们逐一添加到数组的末尾  数组的length属性会跟着更新数据. *push(多个数组元素值) 返回的修改后的数组长度 var array =

js基础--javascript基础概念之数组

js基础--javascript基础概念之数组 在ECMAScript 中 ,数组是很常用的数据类型,js中的数组和其他很多语言的数组有明显的区别.js的数组可以保持任何类型的数值,一个数组中可以保存着多个不同类型的数值.js数组大小(长度)是可以调整的.可以随着数据的添加自动增长数组长度. 创建数组: 一.数组字面量 数组字面量由一对包含数组项的方括号[]表示. var array = [ 'kin', 'cheong', 'change', 'hello', 'haha', 'hi' ];