三消项目相比之前的拼图项目,逻辑上要稍微复杂一些.拓展方面的难度也更大.拆解开来看,主要需要搞清楚五个逻辑:
一,数据与显示分离逻辑:
俗话说万事开头难,是因为想把事儿办成,想让路走的更远,就需要前期做好十足的准备,确保万无一失;三消游戏的开局很好的说明了这样一点.
a,首先需要搭建界面,首先加载一张背景图片作为背景,然后给每个方块添加一个透明方框.这个过程当中需要注意精灵的加载顺序,和坐标的计算.这一段不算复杂.
b,所有的方块都会已精灵的形式加载,但是所有的方块在游戏的过程当中会不断的改变显示图片,并且每一个方块都会有自己的点击事件,以及点击后的处理逻辑.显然比起精灵类Sprite,我们的方块有更多特有的属性,所以我们需要自定义一个继承于Sprite的派生类,用于创建我们后续需要使用的方块精灵对象.代码如下:
”Shard.js”
var Shard = cc.Sprite.extend({
//碎片显示类型
type:0,
listener:null,
ctor:function() {
this._super();
var that = this;
var listener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function (touch, event) {
if(!that.visible) return false;
var target = event.getCurrentTarget();
var location = target.convertToNodeSpace(touch.getLocation());
var targetSize = target.getContentSize();//{width:100,height:100}
var targetRectangle = cc.rect(0, 0, targetSize.width, targetSize.height);
if (cc.rectContainsPoint(targetRectangle, location)) {
cc.eventManager.dispatchCustomEvent(USER_CLICK_SHARD_EVENT, that);
return true;
}
return false;
},
});
this.listener = cc.eventManager.addListener(listener.clone(), this);
},
});
c:所有的精灵您按位置加载好以后,其实只是一个空节点,因为我们在创建自定义的shard对象时,并不会想创建普通的Sprite对象那样传一个图片路径过去用于渲染精灵,之所以如此是因为精灵的显示我们要写成一个函数,以便我们可以随时调用,由此决定什么时候让方块显示,显示哪张图片.所以我们给shard类添加了一个成员函数setType(type),该函数接收一个参数type,type中保存的是用于渲染当前精灵的图片名的数字后缀.(能这样用的前提是我们的图片名称有统一的格式,如icon_1.png, icon_2.png….),代码如下:
”Shard.js”
//设置显示状态
setType:function(_type){
this.type = _type;
if(_type == 0){
this.visible = false;
return
}else{
this.visible = true;
this.initWithFile("res/icon1_"+this.type+".png");
}
},
d,该项目设计中有一个重要的思想,叫数据与显示分离.所谓兵马未动,粮草先行.显示只是驱壳,背后驱动显示的数据才是灵魂.所以我们所有的显示都是在数据处理完毕之后.所以我们会在游戏的主逻辑脚本中定义两个数组,一个用于存储数据(就是每个方块的图片名中的数字后缀),另一个数组用于存储我们自定义的精灵对象即方块.两个数组中的元素时一一对应的,即显示上的位置和数组中的下标对应.该部分代码如下:
”game.js”
var SHARD_TYPE = 8; //方块种类
var SHARD_NUM_W = 8; //横向碎片数量
var SHARD_NUM_H = 8; //纵向碎片数量
var DELAY_TIME = 500; //操作间隔时间
var USER_CLICK_SHARD_EVENT = 'user_click_shard_event'; //自定义事件名称
var GameLayer = cc.Layer.extend({
//碎片数据数组
shard_date_arr:[],
//碎片精灵数组
shard_sprite_arr:[],
//碎片边长
shard_width:0,
//是否有碎片在下落
isInDrop:false,
//已经被选中的碎片
oldShard:null,
//游戏结束状态标签
isGameOver:null,
ctor: function () {
this._super();
this.shard_width = (new cc.Sprite(res.icon_1)).width;
this.shard_date_arr = Creat2X2Arr(SHARD_NUM_W, SHARD_NUM_H, 1);
this.shard_sprite_arr = Creat2X2Arr(SHARD_NUM_W, SHARD_NUM_H, 0);
//初始化游戏
this.initData();
//创建一个即不存在三消也不是死局的开局界面
this.buildWithout3Arr();
//数据处理完毕可以显示界面,开始游戏
this.flushShardShowWithArr();
//自定义事件
cc.eventManager.addCustomListener(USER_CLI