这两天很不顺呀。前不久媳妇骑车被前车徶倒了。昨天我骑车的时候又被外卖车撞的空中翻转了。掉下来头部着地。当时两眼冒金星了。在地上翻滚半天才起来。想着送外卖的也不容易就让他走了。结果推起我的自行车发现我车胎被撞爆了。这个家伙是骑的有多快呀。我通过地下通道里刚漏了个车头就给我怼上了。我昨天也是脑子飘了。光顾着看对面驶来的汽车了。没想到被逆行来的外卖车给我密西了。晚上回去感觉浑身疼。才发现腰部也受伤了。还有脖子也疼的抬不起来。最担心的还是头部。早知道这么严重,当时应该留下那个外卖小哥的。现在后悔已经晚了。想着第二天还是自己掏钱做个检查吧。正好王者荣耀游戏群里有个会算命的老师。半开玩笑的说让老师算一下。最近老是不顺,老是让我提供一个字或者数字,我当时提供了一个字。老师写了半天。说问题不大。顺便把结果给我拍照了。我就发上来让大伙开开眼界。
老师这这样说的:子孙落在小吉宫,位置很好,而且青龙临小吉,也是吉祥之兆,火星本来是灾星但遇土木呈吉祥。所以身体没问题。天空临速喜,亥为水玄武为暧昧不清,天空是虚妄,大概率找肇事人赔偿不太好找了。哈哈。觉得挺有意思哈。玄之又玄。
今天早上起来就赶紧去医院排队检查了。挂的急诊科。头颅CT平扫。30分钟后出了结果。一切正常。脑袋瓜好好的。万幸呀,大难不死必有后福。受伤了真的是难受,浑身疼。估计是撞的时候掉地上把身体的一些软组织震动了。肋骨都疼。估计得好好的缓一阵子了。以后骑车或者走路千万不敢只看一边的车了。疼痛的教训呀。一定要前后左右都看。确定没车在出行。宁等几分不抢1秒。
闲话了这么多。还是继续学习cocos吧。总之大家做什么一定要小心,平安比什么都重要。
二、加载和切换场景
在Cocos Creator的脚本中,可以使用导演类的loadScene方法加载场景,loadScene可以传递一个或两个参数,第一个参数是场景名称,第二个参数是场景加载完毕后的回调函数,场景加载完毕后的回调函数可以进行必要的初始化或数据传递操作,代码如下所示:
cc.director.loadScene("MyScene");
有些场景的加载时间过长,会造成游戏的卡顿,这时我们可以使用预加载的方式,在时间充裕的时候加载场景数据,将这些数据缓存在内存中,这种方式本质上是一种“空间换时间”的方式。预加载的操作代码如下所示:
cc.director.preloadScene("table", function () {
cc.log("Next scene preloaded");
});
引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁。如果我们需要用一个组件控制所有场景的加载,或在场景之间传递参数数据,就需要将该组件所在节点标记为「常驻节点」,使它在场景切换时不被自动销毁,常驻内存。我们使用以下接口:
cc.game.addPersistRootNode(myNode);
上面的接口会将 myNode
变为常驻节点,这样挂在上面的组件都可以在场景之间持续作用,我们可以用这样的方法来储存玩家信息,或下一个场景初始化时需要的各种数据。
取消常驻节点用:
cc.game.removePersistRootNode(myNode);
三 资源管理
3.1 通过资源属性设置和加载资源
在Cocos Creator 中,所有继承自 cc.Asset
的类型都统称资源,如 cc.Texture2D
, cc.SpriteFrame
, cc.AnimationClip
, cc.Prefab
等。它们的加载是统一并且自动化的,相互依赖的资源能够被自动预加载。例如,当引擎在加载场景时,会先自动加载场景关联到的资源,这些资源如果再关联其它资源,其它也会被先被加载,等加载全部完成后,场景加载才会结束。
//脚本中可以这样定义一个 Asset 属性:
cc.Class({
extends: cc.Component,
properties: {
sprite_frame: {
default: null,
type: cc.SpriteFrame
},
}
});
3.2 动态加载资源
Creator 提供了 cc.loader.loadRes
这个 API 来专门加载那些位于 resources 目录下的 Asset。调用时,只要传入相对 resources 的路径即可,并且路径的结尾处 不能包含文件扩展名。
let self = this;
// 加载 Prefab 预制块
cc.loader.loadRes("Player", function (err, prefab) {
let newNode = cc.instantiate(prefab);
self.node.addChild(newNode);
});
图片设置为 Sprite 后,将会在 资源管理器 中生成一个对应的 SpriteFrame。但如果直接加载 test assets/image
,得到的类型将会是 cc.Texture2D。必须指定第二个参数为资源的类型,才能加载到图片生成的 cc.SpriteFrame:
// 加载 SpriteFrame
let self = this;
cc.loader.loadRes("sheep", cc.SpriteFrame, function (err, spriteFrame) {
self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
3.4 资源的释放
loadRes
加载进来的单个资源如果需要释放,可以调用 cc.loader.releaseRes
,releaseRes
可以传入和 loadRes
相同的路径和类型参数。
cc.loader.releaseRes("sheep", cc.SpriteFrame);
cc.loader.releaseRes("sheep");
//可以使用 cc.loader.releaseAsset 来释放特定的 Asset 实例。
cc.loader.releaseAsset(spriteFrame);
四 动作系统
Cocos Creator 提供的动作系统可以在一定时间内对节点完成位移,缩放,旋转等各种动作。Cocos引擎的Action动作类并不是一个在屏幕中显示的对象,动作必须要依托于Node节点类及它的子类的实例才能发挥它的作用,Cocos中的动作不仅包括位置移动等,还包括跳跃、旋转,甚至是对象透明度的变化和颜色的渐变。这些基本动作可以构成各种复杂的动作,也可以通过sequence形成一个完整的动作序列。
4.1基本使用API
// 创建一个移动动作
let action = cc.moveTo(2, 100, 100);
// 执行动作
this.node.runAction(action);
// 停止一个动作
this.node.stopAction(action);
// 停止所有动作
this.node.stopAllActions();
4.2 动作类型
基础动作就是实现各种形变,位移动画的动作,比如 cc.moveTo
用来移动节点到某个位置;cc.rotateBy
用来旋转节点一定的角度;cc.scaleTo
用来缩放节点。基础动作中分为时间间隔动作和即时动作,前者是在一定时间间隔内完成的渐变动作,前面提到的都是时间间隔动作,它们全部继承自 cc.ActionInterval。后者则是立即发生的,比如用来调用回调函数的 cc.callFunc;用来隐藏节点的 cc.hide,它们全部继承自 cc.ActionInstant。
4.2.2 容器动作
容器动作可以以不同的方式将动作组织起来,下面是几种容器动作的用途:
1、顺序动作 cc.sequence
顺序动作可以让一系列子动作按顺序一个个执行。
// 让节点左右来回移动
let seq = cc.sequence(cc.moveBy(0.5, 200, 0), cc.moveBy(0.5, -200, 0));
node.runAction(seq);
2、同步动作 cc.spawn
同步动作可以同步执行对一系列子动作,子动作的执行结果会叠加起来修改节点的属性。
// 让节点在向上移动的同时缩放
let spawn = cc.spawn(cc.moveBy(0.5, 0, 50), cc.scaleTo(0.5, 0.8, 1.4));
node.runAction(spawn);
3、重复动作 cc.repeat
重复动作用来多次重复一个动作。
// 让节点左右来回移动,并重复5次
let seq = cc.repeat(
cc.sequence(
cc.moveBy(2, 200, 0),
cc.moveBy(2, -200, 0)
), 5);
node.runAction(seq);
4、永远重复动作 cc.repeatForever
顾名思义,这个动作容器可以让目标动作一直重复,直到手动停止。
// 让节点左右来回移动并一直重复
let seq = cc.repeatForever(
cc.sequence(
cc.moveBy(2, 200, 0),
cc.moveBy(2, -200, 0)
));
5、速度动作 cc.speed
速度动作可以改变目标动作的执行速率,让动作更快或者更慢完成。
// 让目标动作速度加快一倍,相当于原本2秒的动作在1秒内完成
let action = cc.speed(
cc.spawn(
cc.moveBy(2, 0, 50),
cc.scaleTo(2, 0.8, 1.4)
), 2);
node.runAction(action);
6、不同容器类型是可以复合的,除此之外,我们给容器类型动作提供了更为方便的链式 API,动作对象支持以下三个 API:repeat
、repeatForever
、speed
,这些 API 都会返回动作对象本身,支持继续链式调用。来看一个更复杂的动作:
// 复杂的跳跃动画
this.jumpAction = cc.sequence(
cc.spawn(
cc.scaleTo(0.1, 0.8, 1.2),
cc.moveTo(0.1, 0, 10)
),
cc.spawn(
cc.scaleTo(0.2, 1, 1),
cc.moveTo(0.2, 0, 0)
),
cc.delayTime(0.5),
cc.spawn(
cc.scaleTo(0.1, 1.2, 0.8),
cc.moveTo(0.1, 0, -10)
),
cc.spawn(
cc.scaleTo(0.2, 1, 1),
cc.moveTo(0.2, 0, 0)
)
// 以1/2的速度慢放动画,并重复5次
).speed(2).repeat(5);
4.2.3 动作回调
//动作回调可以用以下的方式声明:
let finished = cc.callFunc(this.myMethod, this, opt);
//cc.callFunc 第一个参数是处理回调的方法,即可以使用 CCClass 的成员方法,也可以声明一个匿名函数:
let finished = cc.callFunc(function () {
//doSomething
}, this, opt);
//第二个参数指定了处理回调方法的上下文context(也就是绑定 this),第三个参数是向处理回调方法的传参。可以这样使用传参:
let finished = cc.callFunc(function(target, score) {
cc.log("动作执行了");
}, this, 100);
//在声明了回调动作 finished 后,您可以配合 cc.sequence 来执行一整串动作并触发回调:
let myAction = cc.sequence(cc.moveBy(1, cc.v2(0, 100)), cc.fadeOut(1), finished);
//在同一个 sequence 里也可以多次插入回调
let myAction = cc.sequence(cc.moveTo(1, cc.v2(0, 0)), finished1, cc.fadeOut(1), finished2);
注意: 在 cc.callFunc 中不应该停止自身动作,由于动作是不能被立即删除,如果在动作回调中暂停自身动作会引发一系列遍历问题,导致严重的 bug。
五 UI系统
一个完整的游戏一般由不同的系统组成,从技术的角度看一般会包含UI系统、动画系统、物理系统和声音系统等。其中开发声音相关的内容在引擎工具的帮助下变得很简单,对于目前市面上的手机游戏来说,特别是2D游戏,除了主要的游戏玩法和战斗以外,主要的工作量都在UI界面的开上。由于使用率和开发量都比较高,Cocos Creator中的UI组件经过多个版本的迭代后,在易用性和功能完整度上都有较大的提升。
5.1 基础渲染组件-精灵组件
再复杂的系统都是由基础的简单系统组成的,UI系统也是如此。复杂的UI组件也是由图片和文字等基础元素组成的,接下来就来介绍Cocos Creator中的基础渲染组件 Sprite 精灵组件。Sprite(精灵)是 2D 游戏中最常见的显示图像的方式,在节点上添加 Sprite 组件,就可以在场景中显示项目资源中的图片。点击 属性检查器 下面的 添加组件 按钮,然后从 渲染组件 中选择 Sprite,即可添加 Sprite 组件到节点上。
5.1.1 Sprite 属性
属性 | 功能说明 |
---|---|
Atlas | Sprite 显示图片资源所属的 Atlas 图集资源。(Atlas 后面的 选择 按钮,该功能暂时不可用,我们会尽快优化) |
Sprite Frame | 渲染 Sprite 使用的 SpriteFrame 图片资源。 |
Type | 渲染模式,包括普通(Simple)、九宫格(Sliced)、平铺(Tiled)、填充(Filled)和网格(Mesh)渲染五种模式 |
Size Mode | 指定 Sprite 的尺寸 Trimmed 表示会使用原始图片资源裁剪透明像素后的尺寸 Raw 表示会使用原始图片未经裁剪的尺寸 Custom 表示会使用自定义尺寸。当用户手动修改过 Size 属性后,Size Mode 会被自动设置为 Custom ,除非再次指定为前两种尺寸。 |
Trim | 勾选后将在渲染时去除原始图像周围的透明像素区域,该项仅在 Type 设置为 Simple 时生效。 |
Src Blend Factor | 当前图像混合模式 |
Dst Blend Factor | 背景图像混合模式,和上面的属性共同作用,可以将前景和背景 Sprite 用不同的方式混合渲染,效果预览可以参考 glBlendFunc Tool |
添加 Sprite 组件之后,通过从 资源管理器 中拖拽 Texture 或 SpriteFrame 类型的资源到 Sprite Frame
属性引用中,就可以通过 Sprite 组件显示资源图像。如果拖拽的 SpriteFrame 资源是包含在一个 Atlas 图集资源中的,那么 Sprite 的 Atlas
属性也会被一起设置。
5.1.2 渲染模式
Sprite 组件支持五种渲染模式:
普通模式(Simple)
:按照原始图片资源样子渲染 Sprite,一般在这个模式下我们不会手动修改节点的尺寸,来保证场景中显示的图像和美术人员生产的图片比例一致。九宫格模式(Sliced)
:图像将被分割成九宫格,并按照一定规则进行缩放以适应可随意设置的尺寸(size
)。通常用于 UI 元素,或将可以无限放大而不影响图像质量的图片制作成九宫格图来节省游戏资源空间。平铺模式(Tiled)
:当 Sprite 的尺寸增大时,图像不会被拉伸,而是会按照原始图片的大小不断重复,就像平铺瓦片一样将原始图片铺满整个 Sprite 规定的大小。
填充模式(Filled)
:根据原点和填充模式的设置,按照一定的方向和比例绘制原始图片的一部分。经常用于进度条的动态展示。网格模式(Mesh)
:必须使用 TexturePacker 4.x 以上版本并且设置 ploygon 算法打包出的 plist 文件才能够使用该模式。
填充模式(Filled)
Type
属性选择填充模式后,会出现一组新的属性可供配置。
属性 | 功能说明 |
---|---|
Fill Type | 填充类型选择,有 HORIZONTAL (横向填充)、VERTICAL (纵向填充)和 RADIAL (扇形填充)三种。 |
Fill Start | 填充起始位置的标准化数值(从 0 ~ 1,表示填充总量的百分比),选择横向填充时,Fill Start 设为 0,就会从图像最左边开始填充 |
Fill Range | 填充范围的标准化数值(同样从 0 ~ 1),设为 1,就会填充最多整个原始图像的范围。 |
Fill Center | 填充中心点,只有选择了 RADIAL 类型才会出现这个属性。决定了扇形填充时会环绕 Sprite 上的哪个点,所用的坐标系和 Anchor 锚点 是一样的。 |
Fill Range 填充范围补充说明
在 HORIZONTAL
和 VERTICAL
这两种填充类型下,Fill Start
设置的数值将影响填充总量,如果 Fill Start
设为 0.5,那么即使 Fill Range
设为 1.0,实际填充的范围也仍然只有 Sprite 总大小的一半。
而 RADIAL
类型中 Fill Start
只决定开始填充的方向,Fill Start
为 0 时,从 x 轴正方向开始填充。Fill Range
决定填充总量,值为 1 时将填充整个圆形。Fill Range
为正值时逆时针填充,为负值时顺时针填充。
5.2 基础渲染组件-Lable组件
Label组件用来显示一段文字,文字可以是系统字,也可以是图片字或者艺术字体,Label组件将文字排好版并且渲染出来。单击属性检查器下面的添加组件按钮,然后就可以在渲染组件中选择Label,将Label组件添加到节点上,Label的属性编辑界面:
5.2.1 Label 属性
属性 | 功能说明 |
---|---|
String | 文本内容字符串。 |
Horizontal Align | 文本的水平对齐方式。可选值有 LEFT,CENTER 和 RIGHT。 |
Vertical Align | 文本的垂直对齐方式。可选值有 TOP,CENTER 和 BOTTOM。 |
Font Size | 文本字体大小。 |
Line Height | 文本的行高。 |
Overflow | 文本的排版方式,目前支持 CLAMP,SHRINK 和 RESIZE_HEIGHT。 |
Enable Wrap Text | 是否开启文本换行。(在排版方式设为 CLAMP、SHRINK 时生效) |
SpacingX | 文本字符之间的间距。(使用 BMFont 位图字体时生效) |
Font | 指定文本渲染需要的字体文件,如果使用系统字体,则此属性可以为空。 |
Font Family | 文字字体名字。在使用系统字体时生效。 |
Cache Mode | 文本缓存类型(v2.0.9 中新增),仅对 系统字体 或 ttf 字体有效,BMFont 字体无需进行这个优化。包括 NONE、BITMAP、CHAR 三种模式。详情见下方的 文本缓存类型。 |
Use System Font | 布尔值,是否使用系统字体。 |
5.2.2 Label 排版
属性 | 功能说明 |
---|---|
CLAMP | 文字尺寸不会根据 Bounding Box 的大小进行缩放,Wrap Text 关闭的情况下,按照正常文字排列,超出 Bounding Box 的部分将不会显示。Wrap Text 开启的情况下,会试图将本行超出范围的文字换行到下一行。如果纵向空间也不够时,也会隐藏无法完整显示的文字。 |
SHRINK | 文字尺寸会根据 Bounding Box 大小进行自动缩放(不会自动放大,最大显示 Font Size 规定的尺寸),Wrap Text 开启时,当宽度不足时会优先将文字换到下一行,如果换行后还无法完整显示,则会将文字进行自动适配 Bounding Box 的大小。如果 Wrap Text 关闭时,则直接按照当前文字进行排版,如果超出边界则会进行自动缩放。注意:这个模式在文本刷新的时候可能会占用较多 CPU 资源。 |
RESIZE_HEIGHT | 文本的 Bounding Box 会根据文字排版进行适配,这个状态下用户无法手动修改文本的高度,文本的高度由内部算法自动计算出来。 |
5.2.3 文本缓存类型(Cache Mode)
属性 | 功能说明 |
---|---|
NONE | 默认值,Label 中的整段文本将生成一张位图。 |
BITMAP | 选择后,Label 中的整段文本仍将生成一张位图,但是会尽量参与 动态合图。只要满足动态合图的要求,就会和动态合图中的其它 Sprite 或者 Label 合并 Draw Call。由于动态合图会占用更多内存,该模式只能用于文本不常更新的 Label。补充:和 NONE 模式一样,BITMAP 模式会强制给每个 Label 组件生成一张位图,不论文本内容是否等同。如果场景中有大量相同文本的 Label,建议使用 CHAR 模式以复用内存空间。 |
CHAR | 原理类似 BMFont,Label 将以“字”为单位将文本缓存到全局共享的位图中,相同字体样式和字号的每个字符将在全局共享一份缓存。能支持文本的频繁修改,对性能和内存最友好。不过目前该模式还存在如下限制,我们将在后续的版本中进行优化: 1、该模式只能用于字体样式和字号固定(通过记录字体的 fontSize、fontFamily、color、outline 为关键信息,以此进行字符的重复使用,其他有使用特殊自定义文本格式的需要注意),并且不会频繁出现巨量未使用过的字符的 Label。这是为了节约缓存,因为全局共享的位图尺寸为 2048*2048,只有场景切换时才会清除,一旦位图被占满后新出现的字符将无法渲染。 2、Overflow 不支持 SHRINK。 3、不能参与动态合图(同样启用 CHAR 模式的多个 Label 在渲染顺序不被打断的情况下仍然能合并 Draw Call) |
注意:
- Cache Mode 对所有平台都有优化效果。
5.3 Button-按钮组件
Button 组件可以响应用户的点击操作,当用户点击 Button 时,Button 自身会有状态变化。另外,Button 还可以让用户在完成点击操作后响应一个自定义的行为。
点击 属性检查器 下面的 添加组件 按钮,然后从 UI 组件 中选择 Button,即可添加 Button 组件到节点上。
5.3.1 Button 属性
属性 | 功能说明 |
---|---|
Target | Node 类型,当 Button 发生 Transition 的时候,会相应地修改 Target 节点的 SpriteFrame,颜色或者 Scale。 |
interactable | 布尔类型,设为 false 时,则 Button 组件进入禁用状态。 |
Transition | 枚举类型,包括 NONE、COLOR、SPRITE 和 SCALE。每种类型对应不同的 Transition 设置。详情见下方的 Button Transition 部分。 |
Click Event | 列表类型,默认为空,用户添加的每一个事件由节点引用、组件名称和一个响应函数组成。详情见下方的 Button 事件 部分。 |
注意:当 Transition 为 SPRITE 且 disabledSprite 属性有关联一个 spriteFrame 的时候,此时将忽略 Enable Auto Gray Effect 属性.
5.3.2 Button Transition
Button 的 Transition 用来指定当用户点击 Button 时的状态表现。目前主要有 NONE、COLOR、SPRITE 和 SCALE 四种类型。
属性 | 功能说明 |
---|---|
Normal | Button 在 Normal 状态下的颜色。 |
Pressed | Button 在 Pressed 状态下的颜色。 |
Hover | Button 在 Hover 状态下的颜色。 |
Disabled | Button 在 Disabled 状态下的颜色。 |
Duration | Button 状态切换需要的时间间隔。 |
Sprite Transition
属性 | 功能说明 |
---|---|
Normal | Button 在 Normal 状态下的 SpriteFrame。 |
Pressed | Button 在 Pressed 状态下的 SpriteFrame。 |
Hover | Button 在 Hover 状态下的 SpriteFrame。 |
Disabled | Button 在 Disabled 状态下的 SpriteFrame。 |
属性 | 功能 |
---|---|
Duration | Button 状态切换需要的时间间隔。 |
ZoomScale | 当用户点击按钮后,按钮会缩放到一个值,这个值等于 Button 原始 scale * zoomScale, zoomScale 可以为负数 |