3.1 搭建Cocos2d-JS v3.x 开发环境
下载所需的软件包
- 下载 Cocos Code IDE。目前 Cocos Code IDE 最新发布版本是 1.0.0-RC2。我们为什么 Cocos Code IDE 呢?因为它是 进行Cocos2d-x Lua 和Javascript游戏开发、调试、发布的完整工具组件。它支持Cocos2d-x v3.x, Cocos2d-JS v3.x及以上版本。Cocos Code IDE 提供了很多特性,例如Javascript代码的语法实现、调试、语法高亮以及自动补全、代码调试、一键部署等功能。
- 从Cocos2d-x的官网下载Cocos2d-JS v3.0。下载完成后解压到适当的路径。
你可以根据自己的系统(Mac/windwos)选择下载相应版本的Cocos Code IDE。
安装&配置Cocos Code IDE
安装
以Mac环境为例,下载Mac版的Cocos Code IDE。双击打开已下载的cocos-code-ide-mac64-1.0.0-rc2.dmg文件。如图:
拖动 Cocos Code IDE 到 Application文件夹进行安装。
安装完成后,打开Cocos Code IDE。
配置
打开工具的 Preferences 页,切换到 Cocos/JavaScript 子页面,选择你刚刚下载 Cocos2d-js v3.0 作为 JavaScript Framework。:
创建一个新项目
通过Cocos Code IDE可以创建新项目,点击 File->New->Cocos JavaScript Project 创建一个新的Cocos2d-JS的项目。弹出如下窗口:
点击 finish 完成创建。
在浏览器中运行
点击工具栏上的按钮
运行截图:
3.2 创建第一个场景
概述
在接下来的章节,我们将学习如何使用Cocos2d-JS制作一个消灭Sushi的小游戏。
游戏运行结果:
首先我们来创建游戏的第一个场景。
基础概念
导演 (Director)是Cocos2d-JS引擎抽象的一个对象,Director是整个Cocos2d-JS引擎的核心,是整个游戏的导航仪,游戏中的一些常用操作就是由Director来控制的,比如OpenGL ES的初始化,场景的转换,游戏暂停继续的控制,世界坐标和GL坐标之间的切换,对节点(游戏元素)的控制等,还有一些游戏数据的保存调用,屏幕尺寸的获取等都要由Director类来管理控制的。
场景(Scene)是Cocos2d-JS引擎抽象的一个对象,用Cocos2d-JS制作游戏就如同拍电影,事实上所有东西都必须放置到一个场景容器中才能最终被显示出来。游戏中我们通常需要构建不同的场景(至少一个),游戏里关卡、界面的切换其实就是一个一个场景的切换,就像在电影中变换舞台或场地一样。
层(Layer)通常包含的是直接在屏幕上呈现的内容,并且可以接受用户的输入事件,包括触摸,加速度计和键盘输入等。每个游戏场景都可以有多个层,每一层都有各自负责的任务,比如专门负责背景显示的层,或显示敌人的层,或UI控件的层等等。
一个场景至少有一个层(Layer)作为孩子节点。
创建场景
创建一个场景,需要如下步骤:
- 在src目录下新建一个StartScene.js空文件。
- 打开project.json,在jsList字段加入StartScene.js的路径。
- "jsList" : [
- "src/resource.js",
- "src/StartScene.js"
]
注:project.json中的jsList用于配置项目所使用的js文件。
- 打开StartScene.js文件,加入下面的场景创建代码。
var StartLayer = cc.Layer.extend({
ctor:function () {
this._super();
var size = cc.winSize;
var helloLabel = new cc.LabelTTF("Hello World", "", 38);
helloLabel.x = size.width / 2;
helloLabel.y = size.height / 2;
this.addChild(helloLabel);
return true;
}
});
var StartScene = cc.Scene.extend({
onEnter:function () {
this._super();
var layer = new StartLayer();
this.addChild(layer);
}
});
cc.Scene.extend是Cocos2d-JS提供的Scene继承方法,这里重写onEnter方法,并在里面初始化自定义的StartLayer。并将StartLayer作为孩子节点添加到Scene上显示。 同样的cc.Layer.extend用来继承Layer,在这个层里面,我们用cc.LabelTTF创建一字符串输添加到层。
- 打开main.js,替换初始化场景的类为我们刚创建的StartScene。
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new StartScene());
}, this);
Cocos2d-JS通过Director管理场景的运行和切换。上面代码运行了我们的StartScene。
经过上面4个步骤,我们创建了游戏的第一个场景,点击运行可以看到下面的效果。
3.3 添加内容到场景
概述
上一节,我们创建了第一个场景,除了显示Hello world的一个文本标签场景还很空,让我们来给消灭Sushi游戏的第一个场景加入背景和开始菜单。
基础知识
在添加内容到场景前,我们需要先了解一下什么是精灵。
精灵(Sprite),Cocos2d-JS中的精灵(Sprite)和其他游戏引擎中的精灵相似,它可以移动,旋转,缩放,执行动画,并接受其他转换。如果说Scene和Layer代表了宏观的游戏管理元素,那么Sprite则为微观世界提供了丰富灵活的细节表现。从静态的树木、房屋到奔跑的敌人、旋转的落叶,我们都可以通过Sprite来实现。
标签(Label),常用于显示文本。在游戏开发中,文字起了非常重要的作用。游戏介绍、游戏中的提示以及对话等都需要用到文字显示。
菜单(Menu),常用于实现菜单按钮。Menu类驱动一个菜单的主类,它包含描述文字、按钮和触发器的菜单列表。在使用过程中,首先你需要创建一个或多个菜单项(MenuItem),然后用这些菜单项初始化菜单(Menu)对象,最后将这个初始化了的菜单对象添加到Layer中。
添加资源文件
将背景图(background.png)和菜单图(start_N.png/start_S.png)添加到项目的res文件夹下。然后编辑resource.js文件,加入资源图片的引用。
var res = {
BackGround_png : "res/background.png",
Start_N_png : "res/start_N.png",
Start_S_png : "res/start_S.png"
};
注:Cocos2d-JS项目使用resource.js文件管理资源文件
添加背景
- 开打StartScene.js,在ctor函数中添加下面的代码。
2.
// add bg
3.
this.bgSprite = new cc.Sprite(res.BackGround_png);
4.
this.bgSprite.attr({
5.
x: size.width / 2,
6.
y: size.height / 2,
7.
});
this.addChild(this.bgSprite, 0);
new cc.Sprite
创建一个精灵bgSprite,通过bgSprite.attr来设置bgSprite的熟悉,这是Cocos2d-JS 3.x的提供的新方法,更高效简洁。然后addChild到当前Layer。
点击运行,可以看到下面的效果。
添加开始菜单
- 在StartScene.js的ctor函数中添加下面的代码
2.
//add start menu
3.
var startItem = new cc.MenuItemImage(
4.
res.Start_N_png,
5.
res.Start_S_png,
6.
function () {
7.
cc.log("Menu is clicked!");
8.
}, this);
9.
startItem.attr({
10.
x: size.width/2,
11.
y: size.height/2,
12.
anchorX: 0.5,
13.
anchorY: 0.5
14.
});
15.
16.
var menu = new cc.Menu(startItem);
17.
menu.x = 0;
18.
menu.y = 0;
this.addChild(menu, 1);
菜单的创建是首先创建一个menuItem对象,然后通过menuItem对象创建menu。最后将menu作为孩子添加到当前的层上。new cc.MenuItemImage
创建了一个图片创建的菜单项,其中res.Start_N_png是菜单正常图片,res.Start_S_png是选中后的状态,其中匿名函数用于处理菜单的响应事件,Cocos2d-JS中用cc.log打印log信息。通过new cc.Menu
创建了菜单menu。
运行查看效果,如图:
点击start按钮,Console输出:
cocos2d: JS: Menu is clicked!
3.4 使用动作让场景活起来
概述
在前面的章节中,我们已经创建了游戏的第一个场景。并介绍了游戏的场景、层和精灵等等构成游戏画面的基本元素的概念,但游戏不仅是由静态画面构成的,更多的时候,游戏是动态效果的呈现,这也是游戏与应用的主要区别。因此,决定一个游戏引擎好坏的重要因素是引擎对动作、动画的支持程度。
在这一节,我将向大家展示如何制作PlayScene,加入掉落的Sushi精灵,学习动画创建。
基础知识
动作(Action),Cocos2d-JS中动作是用来描述游戏节点行为规范的一个类,引擎支持很多动作,其中Action类是所有动作的基类,它创建的每个对象都代表一个动作。动作作用于Node,因此每个动作都需要由Node对象来执行,它本身并不是一个能在屏幕中显示的对象。
创建Play场景
参照前面的创建第一个场景章节,我相信你能很快创建好。
- 在src目录下新建一个PlayScene.js空文件。
- 打开project.json,在jsList字段加入PlayScene.js的路径。
- "jsList" : [
- "src/resource.js",
- "src/StartScene.js",
- "src/PlayScene.js"
]
- 打开PlayScene.js文件,加入下面的场景创建代码。
var PlayLayer = cc.Layer.extend({
bgSprite:null,
ctor:function () {
this._super();
var size = cc.winSize;
// add bg
this.bgSprite = new cc.Sprite(res.BackGround_png);
this.bgSprite.attr({
x: size.width / 2,
y: size.height / 2,
//scale: 0.5,
rotation: 180
});
this.addChild(this.bgSprite, 0);
return true;
}
});
var PlayScene = cc.Scene.extend({
onEnter:function () {
this._super();
var layer = new PlayLayer();
this.addChild(layer);
}
});
- 运行PlayScene,打开main.js,替换初始化场景的类为我们刚创建的PlayScene。
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new PlayScene());
}, this);
点击运行可以看到下面的效果。
添加Sushi精灵
上面我们已经创建好了我们的play场景,让我们来加入sushi精灵吧。
添加sushi精灵资源,将sushi_1n.png拷贝到res文件夹,并编辑resource.js文件,加入资源图片的引用
Sushi_png : "res/sushi_1n.png"
在PlayLayer的ctor方法后加入addSushi方法。代码如下:
addSushi : function() {
var sushi = new cc.Sprite(res.Sushi_png);
var size = cc.winSize;
var x = sushi.width/2+size.width/2*cc.random0To1();
sushi.attr({
x: x,
y:size.height - 30
});
this.addChild(sushi,5);
}
上面代码创建了一个sushi精灵并添加到层上。其中x坐标值随机。cc.random0To1返回0~1之间的随机数值。然后在ctor中调用改方法添加sushi精灵。
this.addSushi();
运行效果如图:
让Sushi精灵动起来
上面的代码,我们创建了静态的sushiSprite,现在我们让它动起来。使它从屏幕顶部下落到屏幕底部。在addSushi方法中添加如下代码:
var dorpAction = cc.MoveTo.create(4, cc.p(sushi.x,-30));
sushi.runAction(dorpAction);
cc.MoveTo使一个Node做直线运动,在规定时间内移动到指定位置。最后精灵调用runAction方法来运行动画。 cc.MoveTo只是Cocos2d-JS中简单动作的一种,还有更多丰富的动作,如MoveBy(移动经过某位置)/JumpTo(跳动到某位置)/BezierTo(贝尔曲线运动到某位置)等持续动作,FadeIn(淡入)/FadeOut(淡出)/FadeTo(渐变)等视觉动作和复合动作Repeat(重复执行动作)/Spawn(同时执行一批动作)/Sequence(使一批动作有序执行)
运行效果如图:
加入更多下落的SushiSprite
如何有序的产生一批源源不断从屏幕底部下落的Sushi?很简单,我们需要加入个定时器来驱动sushi的产生。
首先,加入个定时器,在PlayLayer的ctor方法后加入update方法,并调用addSushi方法代码如下:
update : function() {
this.addSushi();
},
在PlayLayer的ctor方法中加入,定时器,代码如下:
this.schedule(this.update,1,16*1024,1);
在Cocos2d-JS中提供了三种Schedule,其中:
- schedule(callback_fn, interval, repeat, delay) 根据用户指定的参数定时执行
里面四个参数对应的含义是:
callback_fn:调用的方法名
interval:间隔多久再进行调用
repeat:重复的次数
delay:延迟多久再进行调用
- scheduleOnce(callback_fn, delay) 该函数只调用一次callback_fn的方法
- scheduleUpdate()该函数会每一帧都调用,调用的方法名为"update"
上面的代码,创建了一个定时器每隔一秒无限重复执行update函数,添加SushiSprite。当然你也可以使用scheduleUpdate实现。
移除屏幕底部的SushiSprite
上面代码,不断的往屏幕上添加下落的SushiSprite精灵。大量的精灵显示需要消耗很多资源,而且掉落到屏幕底部的SushiSprite已经完成了它的使命。下面我们就添加代码移除屏幕底部的SushiSprite。
首先,为PlayLayer添加属性,SushiSprites数组容器管理SushiSprite。
SushiSprites:null,
在PlayLayer的ctor方法中初始化
this.SushiSprites = [];
在addSushi方法中,将新生成的SushiSprite放人数组
this.SushiSprites.push(sushi);
添加removeSushi方法,移除屏幕底部的SushiSprite
removeSushi : function() {
//移除到屏幕底部的sushi
for (var i = 0; i < this.SushiSprites.length; i++) {
cc.log("removeSushi.........");
if(0 == this.SushiSprites[i].y) {
cc.log("==============remove:"+i);
this.SushiSprites[i].removeFromParent();
this.SushiSprites[i] = undefined;
this.SushiSprites.splice(i,1);
i= i-1;
}
}
},
在update中调用removeSushi方法。
运行效果如图:
3.5 场景转换
概述
在前面的章节,我们创建了带开始按钮的StartScene场景和不断下落的Sushi精灵PlayScene场景。如何把两个场景串联起来,更加生动的切换场景?接下来,我将展示如何实现场景的转换。
基础知识
Cocos2d-JS游戏中游戏界面以场景Scene为单位,每个场景中都设定了一定的主题,包括背景、精灵以及场景规则,将不同的Scene联系起来就组成了游戏全局。一般来讲,游戏在不同场景之间切换时,为了避免游戏的切换看起来特别生硬或突兀,程序设计者们往往需要在切换时加入一定的过渡衔接效果。那么如何在场景间实现华丽丽的切换呢?
这就需要了解一个新的概念,导演(Director)。
一款游戏好比一部电影,它们的基本原理都是一样的,只是游戏具有更强的交互性,所以Cocos2d-JS中把统筹游戏大局的类抽象为导演类(Director)。导演类是游戏的组织者和领导者,是整个游戏的导航仪、总指挥。游戏开始和结束时都需要调用Director的方法来完成游戏初始化或销毁工作。
Director负责控制游戏场景的切换。在Director中常用的替换场景的方法有三个:
- pushScene 终止正在运行的场景,把它放到暂停场景的堆栈(内存)中去,新的场景将被执行。由于将场景放置内存中,场景并没有release。
- popScene 将经过pushScene的场景从堆栈(内存)中pop出来执行(前提是堆栈内存中存在场景),而当前执行的场景将被删除。
- replaceScene 用一个新的场景去替换掉正在运行的场景,正在运行的场景将被终止。
pushScene和popScene这两个方法用来在不释放旧场景内存下运行新的场景,它旨在加快场景交替的速度。不过这里有个令人头疼的问题:如果新、旧场景对内存的需求都不大,可以共享内存,那么无论如何它们切换起来都很快;但如果这两个场景都非常复杂,加载起来很慢,那么使用pushScene和popScene以后,这两个场景会互相争夺宝贵的内存资源,内存使用很快就会达到一个非常危险的级别。
所以这里需要注意的就是,使用pushScene()时,我们应尽量避免将一个大的场景压入堆栈以减少内存的占用。通常情况下常使用的是replaceScene()方法。
场景切换
在main.js,将StartScene作为我们初始化运行的场景,代码如下:
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new PlayScene());
}, this);
在StartScene的开始菜单按钮的响应函数中加入场景切换代码。点击开始按钮切换场景进入到我们的PlayScene。代码如下:
var startItem = new cc.MenuItemImage(
res.Start_N_png,
res.Start_S_png,
function () {
cc.log("Menu is clicked!");
cc.director.replaceScene( cc.TransitionPageTurn(1, new PlayScene(), false) );
}, this);
cc.director用来获取导演单例实体,cc.TransitionPageTurn创建了一个翻页效果的场景切换动画,当然你也可以不使用转场动画。直接传入new SecondScene()。
Cocos2d-JS中场景之间通过TransitionScene系列类来实现过渡跳转的效果。TransitionScene继承于Scene,该系列类主要是与场景切换特效相关的一些使用类。如TransitionFadeDown、TransitionPageTurn、TransitionJumpZoom等等。
注意:转场动画需要小心浏览器的兼容性。比如翻页效果就在浏览器上不支持
点击运行可以看到下面的效果。
3.6 使用事件管理器创建用户交互
概述
在前面的章节,我们已经创建好了游戏的场景,还缺少玩家交互。常见的是touch事件。在这个小游戏中,我们点击下落的Sushi精灵,消灭Sushi,播放Sushi消失动画。接下来将向大家展示如何添加touch事件和播放帧动画。
基础知识
事件
Cocos2d-JS v3.x中事件分发机制进行了重写,事件可以与任意对象绑定,而不是只有Layer才能获取。对象创建自己的事件监听器,然后加入到全局的事件管理器统一管理。
事件监听器有以下几种:
- 触摸事件
- 键盘响应事件
- 鼠标响应事件
- 自定义事件
- 加速计事件
帧动画
帧动画就是很多张图片的序列图实现轮流播放产生动画效果,帧越多动画越流畅。Cocos2d-JS 提供cc.spriteFrame负责管理精灵帧,cc.Animation负责管理动画序列,多长时间内播放多少张帧。cc.Animate负责管理帧动画的动作创建。
帧动画的创建流程:将连续的动作图片生成cc.spriteFrame对象放入到数组。然后通过cc.Animation创建动画序列,再通过cc.Animate制作成帧动画的动作。最后由该节点Node播放帧动画。
SushiSprite响应点击事件
为方便代码管理,在此新建一个SushiSprite.js文件代表SushiSprite。通过使用Cocos2d-JS的类继承方式cc.Sprite.extend实现为精灵类的一个扩展。
- 新建SushiSprite类,代码如下
- var SushiSprite = cc.Sprite.extend({
- onEnter:function () {
- cc.log("onEnter");
- this._super();
- },
- onExit:function () {
- cc.log("onExit");
- }
});
- 添加触摸事件,代码如下:
13.addTouchEventListenser:function(){
- this.touchListener = cc.EventListener.create({
- event: cc.EventListener.TOUCH_ONE_BY_ONE,
- // When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it.
- swallowTouches: true,
- //onTouchBegan event callback function
- onTouchBegan: function (touch, event) {
- var pos = touch.getLocation();
- var target = event.getCurrentTarget();
- if ( cc.rectContainsPoint(target.getBoundingBox(),pos)) {
- cc.log("touched")
- return true;
- }
- return false;
- }
- cc.eventManager.addListener(this.touchListener,this);
});
上面的代码,首先通过使用cc.EventListener.create创建了一个Touch事件监听器touchListener,然后,通过cc.eventManager.addListener注册监听器到事件管理器。cc.EventListener.create扩展出一个用户监听器。event属性,定义这个监听器监听的类型。swallowTouches属性设置是否吃掉事件,事件被吃掉后不会递给下一层监听器。 onTouchBegan方法处理触摸点击按下事件,我们在这里可以获取到触摸点的坐标pos。event.getCurrentTarget()获取当前事件的接受者,并判断当前的是否点击到了SushiSprite。在touch事件中,我们还可以添加onTouchMoved/onTouchEnded方法监听touch移动和结束的回调。如果onTouchBegan返回false后onTouchMoved/onTouchEnded不会执行。
在onTouchBegan方法中获取点击点的坐标pos,然后通过cc.rectContainsPoint(target.getBoundingBox(),pos)判断点击的点是否在SushiSprite上。
3.在onEnter方法中调用addTouchEventListenser 4.修改PlayScene.js中的addSushi的SushiSprite创建
```
var sushi = new SushiSprite(res.Sushi_png);
```
运行并点击下落的SushiSprite,在Console输出下面的log
```
cocos2d: JS: touched
```
SushiSprite消失动画
玩家点击SushiSprite,消灭下落的Sushi,点中的Sushi产生烟雾效果消失。下面我们就来实现SushiSprite消失动画。这里我们采用烟雾帧动画实现。
首先,准备好Sushi消失的帧动画图片。有11张渐变的Sushi消失帧图片,如果我们一张张的从磁盘读取加载,那会非常的慢,还浪费内存资源。还好Cocos2d-JS支持精灵表单(Spritesheet),使用TexturePacker工具,将多张帧图片打包成一张大图和一个.plist文件,通过加载大图可以提高读取速度,并减少内存消耗。Cocos2d-JS中提供了cc.spriteFrameCache管理精灵缓存,通过cc.spriteFrameCache可以方便的读取打包好的大图到内存,根据.plist文件中的信息可以方便获取到各帧图片。 cc.spriteFrameCache.getSpriteFrame(str)方法可以获取到各个精灵帧。
打包的图片和.plist文件如下:
将生成好的资源放到项目的res文件下,并在resource.js文件中添加资源的引用
```
var res = {
...
Sushi_plist : "res/sushi.plist",
Sushi_png : "res/sushi.png"
};
```
首先,在PlayScene.js的ctor方法中加载帧图片到缓存
```
cc.spriteFrameCache.addSpriteFrames(res.Sushi_plist);
```
然后,在SushiSprite.js中添加帧动画的创建代码
```
createDisappearAction : function() {
var frames = [];
for (var i = 0; i < 11; i++) {
var str = "sushi_1n_"+i+".png"
//cc.log(str);
var frame = cc.spriteFrameCache.getSpriteFrame(str);
frames.push(frame);
}
var animation = new cc.Animation(frames, 0.02);
var action = new cc.Animate(animation);
return action;
},
```
其次,为SushiSprite添加一个属性disappearAction保存消失动画,
```
disappearAction:null,//消失动画
```
在onEnter方法中创建disappearAction
```
onEnter:function () {
...
this.disappearAction = this.createDisappearAction();
this.disappearAction.retain();
}
```
上面的retain()方法表示对生成的消失动画增加一次引用。Cocos2d-JS遵循Cocos2d-x的内存管理原则。上面创建的disappearAction是自动释放的,我们需要为它增加一次引用,以避免它被回收,在我们不需要的时候对它执行release()方法,释放对它的引用。避免内存泄露。在使用Cocos2d-JS的jsb模式时,部分情况是需要我们手动管理内存的。
在onExit方法中释放对disappearAction的引用
```
onExit:function () {
cc.log("onExit");
this.disappearAction.release();
this._super();
},
```
最后,在SushiSprite被点中的响应函数onTouchBegan中实现,SushiSprite消失动画的播放,和移除SushiSprite
```
onTouchBegan: function (touch, event) {
...
target.removeTouchEventListenser();
//响应精灵点中
cc.log("pos.x="+pos.x+",pos.y="+pos.y);
target.stopAllActions();
var ac = target.disappearAction;
var seqAc = cc.Sequence.create( ac, cc.CallFunc.create(function () {
cc.log("callfun........");
target.removeFromParent();
},target) );
target.runAction(seqAc);
...
}
```
在SushiSprite被点中后,`removeTouchEventListenser()`移除注册的touch事件避免被再次点击。`stopAllActions()`停止SUshiSprite正在播放的动作。`cc.Sequence`是按序列播放动作。`cc.CallFunc`是Cocos2d-JS中提供的动画播放结束的处理回调。上面的代码通过cc.Sequence创建了Sushi消失的动作序列,并在动作结束后从层上移除SushiSprite.
运行结果:
添加得分和倒计时标签
这部分很简单,在前面章节就介绍了Label的用法。在PlayScene的ctor方法中添加得分和倒计时标签的代码如下:
```
this.scoreLabel = new cc.LabelTTF("score:0", "Arial", 20);
this.scoreLabel.attr({
x:size.width / 2 + 100,
y:size.height - 20
});
this.addChild(this.scoreLabel, 5);
// timeout 60
this.timeoutLabel = cc.LabelTTF.create("" + this.timeout, "Arial", 30);
this.timeoutLabel.x = 20;
this.timeoutLabel.y = size.height - 20;
this.addChild(this.timeoutLabel, 5);
```
上面代码分别创建了一个显示得分和计时的标签。
运行结果:
游戏结束逻辑处理
游戏已经完成得差不多了,还差玩家得分的更新和计时器结束游戏。
更新游戏得分
在PlayScene中新建addScore方法
```
addScore:function(){
this.score +=1;
this.scoreLabel.setString("score:" + this.score);
}
```
在SushiSprite的点中响应函数中调用addScore更新得分
计时器结束游戏
我们需要游戏添加一个结束处理,简单的就是使用倒计时,比如60S倒计时结束游戏。倒计时可以使用前面介绍的Schedule实现。
在PlayScene中添加timer方法
```
timer : function() {
if (this.timeout == 0) {
//cc.log('游戏结束');
var gameOver = new cc.LayerColor(cc.color(225,225,225,100));
var size = cc.winSize;
var titleLabel = new cc.LabelTTF("Game Over", "Arial", 38);
titleLabel.attr({
x:size.width / 2 ,
y:size.height / 2
});
gameOver.addChild(titleLabel, 5);
var TryAgainItem = new cc.MenuItemFont(
"Try Again",
function () {
cc.log("Menu is clicked!");
var transition= cc.TransitionFade(1, new PlayScene(),cc.color(255,255,255,255));
cc.director.runScene(transition);
}, this);
TryAgainItem.attr({
x: size.width/2,
y: size.height / 2 - 60,
anchorX: 0.5,
anchorY: 0.5
});
var menu = new cc.Menu(TryAgainItem);
menu.x = 0;
menu.y = 0;
gameOver.addChild(menu, 1);
this.getParent().addChild(gameOver);
this.unschedule(this.update);
this.unschedule(this.timer);
return;
}
this.timeout -=1;
this.timeoutLabel.setString("" + this.timeout);
},
```
上面代码,在60s倒计时结束时,在游戏PlayScene上加入了一个GameOver的提示层,并提供了tryagain菜单。并停止添加SushiSprite和倒计时的Schedule。
然后在PlayScene的ctor方法中实现定时器
```
//timer倒计时60
this.schedule(this.timer,1,this.timeout,1);
```
每个1s调用一次timer方法。
游戏完整运行效果图:
总结
到此,我们的Sushi掉落小游戏就完成了。我们对Cocos2d-JS也有一定的了解,在游戏的制作中,学习了场景,精灵,菜单,标签,动作,事件等,对Cocos2d-JS的API有一定的了解。相信大家不会满足于此,会使用Cocos2d-JS制作出更好的游戏。