.

游戏开发者如何应用CocosCreato

作者

张晓衡

责编

郭芮

本文详解介绍了CocosCreator这一游戏开发方案。CocosCreator包括cocos2d-x引擎的JavaScript实现,能让用户快速开发游戏所需要的各种图形界面工具。目前,其支持发布游戏到Web、iOS、Android、各类小游戏、PC客户端等平台,能够实现全平台运行。

CocosCreator基础教程(1)——从zIndex开始

从Cocos2d-x/lua/js过来的老程序员们肯定发现了,在CocosCreator属性检查器中Node节点竟然没有zIndex属性?

因为这一点,UI节点的遮挡关系控制不便,经常让策划、测试、甚至老板找程序员麻烦。不知道大家有没想过用编辑器去控制zIndex呢,请思考一下?我发现自己是用了CocosCreator快一年才去想到这个问题的。

要用编辑器控制,最简单的方案就是编写组件脚本。

/***SetZIndex.js控制组件**/cc.Class({extends:cc.Component,//编辑器属性定义properties:{zIndex:0},onLoad(){this.node.zIndex=this.zIndex;}});

代码非常简单,将这个组件脚本挂载到任意节点上,通过zIndex属性就能控制节点的zIndex了,看下图:

SetZindex组件

但上面的代码有两个小问题,不仔细还不易被发现:

“zIndex:0”,这样定义zIndex属性,它是一个浮点数类型,你可以在编辑器设置0.1这样的值。运行在浏览器或H5环境没什么问题,但跑在原生环境zIndex对应的是cocos2d-x中的Node::setLocalZOrder(intlocalZOrder)函数,它的参数类型是整型。这个组件只在onLoad时设置了节点的zIndex,如果运行过程中,给这个组件的zIndex属性赋值没有任何作用,并且在编辑器中,你设置zIndex也看不到节点层级的变化。知道问题了就好办了,看下面的代码:

/***SetZIndex.js控制组件**/cc.Class({extends:cc.Component,//编辑器属性定义properties:{zIndex:{type:cc.Integer,//使用整型定义default:0,//使用notify函数监听属性变化notify(oldValue){//减少无效赋值if(oldValue===this.zIndex){return;}this.node.zIndex=this.zIndex;}}},onLoad(){this.node.zIndex=this.zIndex;}});

使用一个对象来定义zIndex属性,同时监听zIndex的修改,问题解决。

SetZIndex组件不依赖任何其它组件和节点,可以挂载任意节点之上,因此它是一个通用组件。不要小看了这个组件的设计,它蕴涵了CocosCreator的组件编程模式和思想。

CocosCreator基础教程(2)——聊聊scale与size属性

在CocosCreator引擎编辑中,节点的scale和size属性都可以改变节点内容的大小。如下图中可爱的椰子头,原图尺寸为*,在UI编辑时发现太大了,需要*的大小更适合。

scalesize

此时将节点scale属性设置为0.25好,还是将size属性的高\宽设置好?回忆一下你在做UI编辑时,习惯用那个属性控制节点大小,思考一下怎样做才是UI开发的最佳实践?

scale与size的区别

scale:节点整体的缩放比例,影响所有子节点。可使用scaleX、scaleY控制节点X\Y轴的缩放。size:节点内容尺寸,以像素为单位,修改size不影响子节点。size是一个对象,使用width\height控制宽\高像素尺寸。通过上面属性说明,比较容易看出scale与size的区别有两点:

scale使用比例单位,size使用像素单位;scale影响子节点,size不影响子节点。在API接口上,scale可以直接使用node.scale访问,但size却不行,需要过node.getContentSize()\node.setContentSize()这两个函数访问,不过size支持node.width\node.height属性访问控制宽高。

虽然scale/size两个属性都可以改变节点的大小,但是当这两个属性同时发生了变化,如何获取节点的实际像素大小用呢?比如说,将上面截图中的椰子头节点scaleX\Y改为0.5,sizeW/H改为,它会变成下面这样:

scalesize同时修改

你会发现,节点只有原来的1/16大小了,它的实际像素计算如下:

width=node.width*node.scaleXheight=node.height*node.scaleY再进一步,如果它的父节点也被缩放了,那当前节点的实际像素尺寸又怎么计算呢?还好有引擎提供有API获取节点包围盒的大小,也就是节点实际看到的像素尺寸:

//节点在父节坐标系下的轴向对齐的包围盒rect1=node.getBoundingBox()getBoundingBox返回的是一个矩形cc.Rect对象的实例,其中的width\height就是节点的像素尺寸,x\y是矩形在父节点下的左下角位置。

有人可能会问,获取节点的实际尺寸有什么呢?最为常用情景就是做碰撞检测,简单的矩形碰撞并不会用到碰撞组件,而是使用cc.rectContainsPoint\cc.rectContainsRect这类函数做检测,例如:

触摸一个节点时,检查触摸点是否在节点区域中;检查将一个节点是否在另一个节点之区域内。检查一下你的项目代码,是否有直接使用getContentSize()或width\height获取节点大小做类似上面的碰撞检测,尝试修改节点的scale属性看看是否还能正常工作。

修改scale属性,节点的size并不会变化。由此也可以看出,使用scale修改节点外观大小不是一个好主意;简单的使用getContentSize()获取节点大小也不是一个安全之举,你不能保证UI编辑的同学不会使用scale属性,所以使用node.getBoundingBox()才是安全之道。

图片尺寸变化对精灵节点的影响

在游戏开发中,时常会遇到图片资源更改的情况,比如:有一系列的角色图片,切图为*的尺寸,但在游戏中只需要*或其它尺寸展示。

后来发现之前的切图过大,包体体积不理想,于是要求美术将其改为*的尺寸。这时做UI编辑的同学可能会被郁闷到,在UI编辑器中,他使用的是scale调整的精灵大小,那图片更新还得再全部重新调整,因为它会以图片原始尺寸的变化而按比列变化。

如果之前使用的是size属性控制的精灵尺寸,同时Script组件设置的sizeMode为CUSTOM(当修改精灵节点的size属性时Sprite组件的sizeMode会自动变为CUSTOM模块,默认为TRIMMED),那图片的尺寸变化就不会影响精灵在游戏中的尺寸变化,所以size属性在这次胜出。

通过上面的举例,还说明了一个问题,将游戏中的关键元素的尺寸预先规定下来非常的重要,这也就是在确定所说的设计尺寸。设计尺寸不仅仅只是屏幕设计尺寸用于规定背景图的大小,还包括统一的角色、图标、UI等等。

Sprite组件对图片大小的约束

上面提到了Sprite组件的sizeMode属性可以配合节点size对图片大小进行约束:

Sprite组件的SizeMode属性

当sizeMode设置为CUSTOM时,不论图片尺寸是多大,当精灵帧spriteFrame变化时(可以尝试拖动不同尺寸的图片到spriteFrame属性上)都不会影响当前节点的size大小。如果你选择的是其它值,当spriteFrame变化时节点size也会随之变化。

scale则不然,scale会在size的基础上再做缩放,所以scale保持为1是最安全的,size属性又得1分。

精灵的九宫模式

Sprite组件的type属性为SLICED时可开启精灵的九宫模式,当编辑好九宫属性后,用节点size属性可无限放大节点。

精灵九宫

需要特别注意的是,九宫属性只适合将精灵节点放大,而不适合将节点缩小,如果九宫的边缘像素占比较大,缩小后会导致精灵变形。

因此使用九宫属性的图片尺寸尽量可能的要小,同时最好不要叠加scale属性,这会让精灵变形更为严重,size属性再得1分。

scale属性的应用

从上面得分来看scale属性好惨,根据我这些年的经验来看将其保持为1是最安全的,所以scale属性尽量少用(默认为1)。

说scale属性一无事处,确实也不太地道,scale属性至少有下面3个用处:

用于cc.ScaleTo/cc.ScaleBy的Action动画;用于有子节点的复杂界面的整体缩放,比如对一个预制件进行缩放;将scaleX或scaleY设置为负数,实现图片的左、右、上、下镜像减少资源量,比如下图中两个精灵这是同一张图片。

设置ScaleX为负数,实现向左镜像

所以scale属性的作用就如同它的名字一样:缩放!不仅可以放大、缩小,还可以向负数做缩放。

回到最初的问题,设置节点的大小使用size将是最佳的实践。这有助于在UI的编辑与设计,同时预先规划好游戏元素的设计尺寸、资源的文件名,无需太多考虑图片素材的尺寸,使用临时图片即可开始项目的开发。

CococsCreator基础教程(3)——meta的秘密

CocosCreator会为assets目录下的每一个文件和目录生成一个同名的meta文件,那meta文件有什么作用呢?下面我们就来说下meta,理解了CocosCreator生成meta文件的作用和机理,能帮助你和你的团队解决在多人开发时常会遇到的资源冲突、文件丢失、组件属性丢失等问题。

脚本丢失

先看下一个场景文件的meta长什么样子:

{ver:1.0.0,//版本uuid:ae-98b2-4f4f-f-36bf7ce3,//全局唯一idasyncLoadAssets:false,//异步加载autoReleaseAssets:false,//自动释放资源subMetas:{}//子元数据}

场景与预制件的meta都长的一个样,再看一个png图片的:

{ver:1.0.0,uuid:ebf-4dda-4c90-99d7-34b2aef4d,type:sprite,wrapMode:clamp,filterMode:bilinear,subMetas:{img_circular:{ver:1.0.3,uuid:a2d1f-6c18-4f67-9ad6-97b35f1fcfcf,rawTextureUuid:ebf-4dda-4c90-99d7-34b2aef4d,trimType:auto,trimThreshold:1,rotated:false,offsetX:0,offsetY:0,trimX:0,trimY:0,width:,height:,rawWidth:,rawHeight:,borderTop:0,borderBottom:0,borderLeft:0,borderRight:0,subMetas:{}}}}

图片文件meta信息比较多,除了基本的ver和uuid外,还记录了图片的高宽、偏移、九宫格等数据。上面这么多信息,我们这里只关心一个:uuid,通用唯一标识符(UniversallyUniqueIdentifier)。

uuid是CocosCreator用来管理游戏资源的,它会为每个文件分配一个唯一的id,图集会生成多个。由此可以了解在CocosCreator引擎中,识别一个文件不是简单地通过路径+文件名定位,而是通过uuid来引用文件。因此可以在编辑器资源管理中,随意删除、移动文件。

CocosCreator生成meta文件有以下几种情况:

打开工程时。CocosCreator引擎在工程刚被打开时,先扫描assets目录,如果哪个文件还没有meta文件,此时就会生成。

更新资源时。更新资源也会引发meta文件的更新:

通过引擎编辑器资源管理窗口,可以对资源进行文件名修改、改变目录、删除文件,添加文件可以从桌面或操作系统的文件管理器将文件拖入引擎资源管理器中。

拖动图片到资源管理器

还有一种情况是在操作系统的文件管理器中对assets目录中的文件进行增、删、改之后,激活引擎编辑器窗口,此时可以看到资源管理器刷新的过程。

资源刷新

如果一个文件的meta文件不存在,上面两种情况都会触发引擎去生成meta文件。

下面我们分析下meta文件出错的几种可能情况。

uuid冲突

uuid是全局唯一的,产生冲突肯定是有不同的文件的uuid相同了,一旦出现这个问题会导致CocosCreator资源管理器目录结构加载不完整,看下图,遇到这种情况估计会让你吓出一身冷汗:

CocosCreatorUUID冲突

从提示中可以看到冲突的uuid字符串,打开操作系统文件管理或代码编辑器,搜索这个uuid:

搜索uuid,找到两个相同的

这时先关闭CocosCreator,然后再任意删除其中一个meta文件,再打开CocosCreator问题可以解决。

这种方法虽然可以解决问题,但如果在编辑器中曾经引用过这个资源的地方将会出现资源丢失,你需要重新编辑或配置一次。最好是通过版本管理工具还原此meta文件。

据我观察,出现这种问题的原因有两个:

在操作系统的文件管理器中移动文件时,将剪切、粘贴操作不少心弄成了复制、粘贴,同时也把meta文件也复制过去了。导致项目中同时出现两个相同的meta文件。在多人协作时,从版本管理工具中,更新资源时碰巧遇到别人生成的uuid与你的电脑上某个文件生成的uuid一样了,但这种情况非常罕见。

总的来说,要解少uuid冲突发生,最好在引擎资源管理工具中进行添加、移动文件。

uuid变化

还有种情况是uuid变了,你曾经编辑的界面将会出现资源、图片丢失,还可能出现组件属性丢失。

uuid变化,编辑器资源丢失

通过Creator控制台的警告可以看到,有曾经被使用过的资源uuid,但现在丢失了。提示还是很详细的,给出了所在的场景文件名、节点路径、组件、uuid,通过提示可以快速定位资源丢失的地方。

这种情况又是怎么造成的呢?一种情景是在新资源添加进项目时,忘记了激活一下CocosCreator让其生成meta文件,同时又将这些新增的文件提交到了版本管理中(不包含meta文件)。之后,有同学去更新了他提交的资源,同时打开或激活了CocosCreator进行编辑,这时Creator会检查到新资源没有meta便会立即生成。这样两个同学的电脑上为同一个文件,生成的meta文件中的uuid都不相同。

这种情况下,后面进行资源提交或更新的同学,肯定也会遇到冲突,如果不明就理就强行解决冲突,就会产生上面的问题,同时把问题蔓延到别的人身上。下面时序图,描述了这种错误的工作流程:

资源更新流程

上面就因第一个A同学忘记生成meta并提交,导致这个严重的问题,每个人都编辑过项目,但每个人生成的uuid都不同。如果不明其理,会陷入无限的资源出错中,做好的东西,一提交更新又出问题了。

要解决这个问题注意下面几点:

提交前检查是否有新增文件,有新增文件时,注意是否有meta文件,需要一起提交。拉取文件时,注意是否有新增文件,并且是有meta文件成对,如果没有提醒之前提交文件的同学,把meta文件一并提交。提交时,如果发现只有新增的meta文件,那这个meta文件肯定是自己生成的,那注意是否使用过这个meta文件对应的资源(同名文件)。如果没用过,那请这个文件最早提交者把meta文件提交了。千万不能将这个meta文件提交上去。

注意上面几点基本上就可以杜绝meta文件uuid变化导致的工程出错了。

meta文件是CocosCreator用于资源管理的重要手段,但在多人协同开发中稍有不慎就容易产生资资源错误。要解决这个问题,不仅需要理解meta文件的产生机制和导致冲突的原因,同时还应该规范资源提交流程。

CocosCreator基础教程(4)——color属性的妙用

在CocosCreator中巧妙利用节点的color属性,改变精灵的颜色,可以有效减少美术资源。我们一起来看看CocosCreator的HelloWorld工程:

背景节点的Color属性

看上图,这次我们的重点不在可爱的椰子头节点上,而是在背景background节点上。它是由一个高宽2像素的纯白色(#FFFFFF)图片渲染而成,但节点的color属性为#1BE,同时注意,节点的高宽充满了整个画布,你可以通过size属性(没有使用scale哦)自由调整节点的尺寸大小。

回想一下,在你的工程中,有没有切出一大块纯色图片做背景?如果有的话这就是一个可优化的点!我们来看看充分发挥color的作用需要注意些什么。

颜色叠加

要想使用color属性精确控制精灵颜色,图片要尽量使用白色,因为color属性并不是简单地设置颜色,而是用纹理像素的rgb与节点的color的rgb相乘(r*color.r、g*color.g、b*color.b)。

节点的Color效果

看上图,在场景编辑器中,椰子头和一个纯红色的精灵节点,都设置为黄色(#FFFF00)。椰子头覆盖上了一层黄色,再看纯红色的精灵则没什么颜色变化,另外注意椰子头整体颜色变暗了,由此得出下面几条经验:

最好在纯白色的精灵上使用color属性,可以精确控制颜色;在非纯色的精灵上使用color属性,整体色调会变暗;纯红、绿、蓝的三元色精灵使用color属性,颜色只能在当前图片颜色范围变化,应用范围有限。

color属性在字体上的应用

上图中,我不仅在精灵组件上设置了颜色,同时也设置了它们下方的Label文本节点的颜色。使用系统字体,引擎默认渲染出的文本是白色的,叠加任意color属性,可以精确控制颜色。

通过修改字体的color属性可以很方便实现一些效果,比如:使用红色Label做受伤时的hp减少;使用绿色Label实现hp的回复;

但是这里有个问题,项目中我们经常使用的并不是系统字体,而是位图字体,也就是由图片制作的字体,看下图:

艺术字体

上图使用的是Atlas艺术字体,关于自定义字体相关的内容我们以后再说。这里可看到绿色Label的文本是由字体文件中的图片构成,也使用了图片的颜色。但这里有个小小的遗憾,这个字体图片使用了个纯RGB三元色中的的绿色,它的颜色变化范围有限,只能用于hp回复这类场景,要给它叠加红色只会让你失望,看下图:

绿色字体叠色后变黑色了

所以在制作字体时,尽量先用纯白色,或者再用点浅灰色做字体外发光,这样可以让字体文件的使用范围更大,发挥更大的价值。

透明度对节点影响

透明度也是color属性的一个组成部分,但透明(opacity)会影响到子节点,RGB则值不会。

不知道你是否注意到美术切出的图片,应用到游戏被引擎渲染出来时,在颜色上总是觉得有所偏差,这里有一个很重要原因就是:透明度。如果一个精灵节点设置了透明度,你看到的并不是这个精灵所表现出来的颜色,而是当前这个精灵与它背后的颜色重叠后色彩,看下图:

透明度对图片的影响

中间和左边两个精灵透明(opactiy)为,但中间的这个精灵节点放在了一个白色图片的上面,精灵节点的颜色与它的背景颜色做了叠加。最右边的精灵没有设置透明,与最左边对比,左边精灵的颜色要暗些,也是因为透过了当前节点加入了背景色的原因。

不仅设置节点的透明属性会影响到精灵的颜色表现,如果原始图片带有透明通道同样会影响到图片在布局时的颜色表现。它与不同的背景色重叠会产生不同的颜色偏差,因此用作背景的图片不论尺寸大小,纹理内容区域尽量不要设置透明(不规则边缘不在此列),这样做不仅避免颜色重叠产生的不一至,而且让图片所占用的磁盘空间、内存空间也会更小。

节点color可以控制精灵的渲染颜色,灵活运用可以减少图片资源。color属性不仅可以作用于精灵,更多的是应用于Lable标签,使用白色纹理,可以让图片更具灵活性。

另外需要注意,图片的透明和节点的透明度都会影响游戏最终渲染出的颜色效果,合理利用color、size、锚点、旋转、九宫等属性特性,扬长避短,可以让游戏更加出色。

CocosCreator基础教程(5)—资源结构

对于游戏开发来说,除了编辑游戏界面、制作游戏动画、编写代码这些具体的工作外,大家还需要对游戏资源结构要非常清楚。如果马虎上阵,等你把项目运作做起来后,一是工作效率不会太高,二是难以精确控制资源,最后甚至会因此陷入混乱。

资源是指用于游戏内容创作所需要的素材,对于CocosCreator工程来说就是assets目录下的文件,看下图:

资源目录结构

那资源结构就是将众多的资源文件按一定的规则存放和命名,以方便使用管理。

看上图所示,我把资源大致分为以下几类:

动画:animation预制:prefab场景:scene脚本:scripts纹理:textures声音:sound配置:config

其中纹理可再细分为:动画帧、背景、字体、UI、图标等(将动画帧图片放到动画目录中会更好,这样可以将动画资源与项目做分离)。分类目录也不要过细,过细会增加重复文件(同名或不同名但内容)出现机率,同时将通用资源和专用资源分开存放,可以再次减少重复文件的产生。

代码的分类也需要注意,我通常将CocosCreator通用组件(纯脚本组件)放在


转载请注明:http://www.abachildren.com/sstx/3356.html