上周做了一个helloworld,这周做一个点击消除小游戏。先上图看下效果。
首先分析下游戏需求:
1.添加背景
2.添加开始游戏按钮
两种状态:初始状态和点击时
3.添加精灵(下落的星星)
随机位置生成星星;
星星下落;
星星到最下面时消失;
星星点击消失;
4.添加分数
添加分数文本;
星星消失时计分累计;
下面从cocos2d的实现上进行分析:
场景:2个,开始页面和游戏页面;
场景一:
精灵两个:背景、开始菜单;
场景二:
精灵三个:背景、分数、星星;
因为游戏比较简单 所以没有进行分层;
接下来进行代码实现:
场景一:
1.添加背景,在StartScene.js的ctor函数中添加下面的代码
ctor: function () {
this._super();
var size = cc.winSize;
//加个背景
this.bgSprite = new cc.Sprite(res.BackGround);
this.bgSprite.attr({
x: size.width / 2,
y: size.height / 2,
});
this.addChild(this.bgSprite, 0);
}
new cc.Sprite
创建一个精灵bgSprite,通过bgSprite.attr
来设置bgSprite的属性;
2.添加开始菜单,在StartScene.js的ctor函数中添加下面的代码
//加菜单
var startItem = new cc.MenuItemImage(
res.Start_Link_png,
res.Start_Active_png,
function () {
cc.log("Menu is clicked!");
}
,this)
startItem.attr({
x: size.width / 2,
y: size.height / 2,
anchorX: 0.5,
anchorY: 0.5,
scale:0.5
});
var menu = new cc.Menu(startItem);
menu.x = 0;
menu.y = 0;
this.addChild(menu, 1);
菜单的创建是首先创建一个menuItem对象,然后通过menuItem对象创建menu。最后将menu作为孩子添加到当前的层上。new cc.MenuItemImage
创建了一个图片创建的菜单项,其中res.Start_Link_png
是菜单正常图片,res.Start_Active_png
是选中后的状态,其中匿名函数用于处理菜单的响应事件,Cocos2d-JS中用cc.log
打印log信息。通过new cc.Menu
创建了菜单menu。
场景二:
首先创建场景二,加背景
var PlayLayer = cc.Layer.extend({
bgSprite:null,
ctor:function () {
this._super();
var size = cc.winSize;
// 加背景
this.bgSprite = new cc.Sprite(res.BackGround);
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);
}
});
下面创建星星,让星星随机位置生成,下落,在到底时消失
在PlayLayer的ctor方法后加入addSushi、removeSushi、update方法。代码如下:
addSushi: function () {
var sushi = new SushiSprite(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,
scale: 0.5
});
var dorpAction = cc.MoveTo.create(3, cc.p(sushi.x, -30));
sushi.runAction(dorpAction);
this.addChild(sushi, 5);
this.SushiSprites.push(sushi);
},
removeSushi: function () {
for (var i = 0; i < this.SushiSprites.length; i++) {
if (0 > this.SushiSprites[i].y) {
this.SushiSprites[i].removeFromParent();
this.SushiSprites[i] = undefined;
this.SushiSprites.splice(i, 1);
i = i - 1;
}
}
},
update: function () {
this.addSushi();
this.removeSushi();
},
现在我们需要加入个定时器来驱动星星的产生。在PlayLayer的ctor方法中加入,定时器,代码如下:
this.schedule(this.update,1,16*1024,1);
定时器使用说明:
schedule(callback_fn, interval, repeat, delay)
根据用户指定的参数定时执行
里面四个参数对应的含义是:
callback_fn:调用的方法名
interval:间隔多久再进行调用
repeat:重复的次数
delay:延迟多久再进行调用
接下来设计星星的交互,为方便代码管理,在此新建一个SushiSprite.js文件代表SushiSprite。通过使用Cocos2d-JS的类继承方式cc.Sprite.extend实现
为精灵类的一个扩展。
实现功能:监听精灵被点击,删除
var SushiSprite = cc.Sprite.extend({
touchListener: null,
onEnter: function () {
cc.log("onEnter");
this._super();
this.addTouchEventListenser();
},
onExit: function () {
cc.log("onExit");
},
addTouchEventListenser: function () {
this.touchListener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function (touch, event) {
var pos = touch.getLocation();
var target = event.getCurrentTarget();
if (cc.rectContainsPoint(target.getBoundingBox(), pos)) {
cc.log("touched")
//响应精灵点中
cc.log("pos.x=" + pos.x + ",pos.y=" + pos.y);
//停止所有的动画
target.stopAllActions();
//从层中删除
target.removeFromParent();
//调用层中的addScore进行计分
cc.director.getRunningScene().getChildByTag(1).addScore()
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上。
通过cc.director.getRunningScene().getChildByTag(1)
获得层的加分方法addScore。
下面我们要加入分数精灵和加分方法addScore:
在PlayScene的ctor方法中添加得分
//添加分数
this.scoreLabel = new cc.LabelTTF("score:0", "Arial", 10);
this.scoreLabel.attr({
x: size.width / 2 + 70,
y: size.height - 20
});
this.addChild(this.scoreLabel, 5);
在PlayScene中新建addScore方法
addScore:function(){
this.score +=1;
this.scoreLabel.setString("score:" + this.score);
}
到现在为止,我们想要的功能就都实现了,最后剩下的就是场景之间的切换:
在main.js,将StartScene作为我们初始化运行的场景,代码如下
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new StartScene());
}, this);
在StartScene的开始菜单按钮的响应函数中加入场景切换代码。点击开始按钮切换场景进入到我们的PlayScene。代码如下:
var startItem = new cc.MenuItemImage(
res.Start_N_png,
res.Start_S_png,
function () {
cc.log("Menu is clicked!");
cc.director.runScene(new PlayScene());
}
,this)
以上,我们的这个小游戏就做好了,下周会根据学习进度再更新一个小游戏(如果有时间看的话 ~)。