用cocos2d-html5做的消除类游戏《英雄爱消除》(2)——Block设计实现

Block可以说是这个游戏的核心类,它除了包含自身的一些属性和方法外还添加了对触摸事件的响应。

我们先来看下源码吧
/**

 * Power by  html5中文网(html5china.com)

 * author: jackyWHJ

 */

var Block = cc.Sprite.extend({

    id:0,

    name:"",

    active:true,

    pointX:0,

    pointY:0,

    beginPoint:null,

    flash:false,

    ctor:function (arg) {

        this._super();

        if(!arg)return;

        this.initWithSpriteFrameName(arg);

        this.name = arg;

//        cc.registerTargetedDelegate(0,true,this);

        cc.Director.getInstance().getTouchDispatcher().addTargetedDelegate(this, 0, true);

    },

    //销毁隐藏

    destroy:function () {

        var explosion =Explosion.getOrCreateExplosion();

        explosion.setPosition(this.getPosition());

//        SparkEffect.getOrCreateSparkEffect(this.getPosition());

        if(LLK.SOUND){

            cc.AudioEngine.getInstance().setMusicVolume(0.7);

            cc.AudioEngine.getInstance().playEffect(s_explodeEffect_mp3);

        }

     this.setVisible(false);

        this.active = false;

        LLK.COUNT --;

        if(LLK.COUNT <= 0/* || 1*/){

            g_sharedGameLayer.onGameOver();

        }

    },

 

    //判断触摸点是否在图片的区域上

    containsTouchLocation:function (touch) {

        //获取触摸点位置

        var getPoint = touch.getLocation();

 

        //物体当前区域所在的位置

        var contentSize  =  this.getContentSize();

        var myRect = cc.rect(0, 0, contentSize.width, contentSize.height);

        myRect.origin.x += this.getPosition().x;

        myRect.origin.y += this.getPosition().y;

        //判断点击是否在区域上

        return cc.rectContainsPoint(myRect,getPoint);

    },

    //刚触摸瞬间

    onTouchBegan:function (touch, event) {

        if (!this.containsTouchLocation(touch)) return false;

        this.beginPoint = touch.getLocation();

//        this.setZIndex(100);

        this.flash = true;

        this.setScale(1.2);

        return true;

    },

    //触摸移动

    onTouchMoved:function (touch, event) {

        if (!this.containsTouchLocation(touch)) return false;

        var touchPoint = touch.getLocation();

        var xDist = touchPoint.x - this.beginPoint.x,yDist = touchPoint.y - this.beginPoint.y;

        //移动距离超过10个像素位才有效

        if((Math.abs(xDist) >= 10 || Math.abs(yDist) >= 10)&&this.flash){

            this.flash = false;

            var block = this;

            if(Math.abs(xDist) > Math.abs(yDist)){

                if(xDist > 0){this.moveRight(block);}

                else{this.moveLeft(block);}

            }

            else{

                if(yDist > 0){this.moveUp(block);}

                else{this.moveDown(block);}

            }

            return false;

        }

    },

    onTouchEnded:function(touch,event){

        this.setScale(1);

        this.flash = true;

    },

 

    moveLeft:function(block){

        if(block.pointX == 0)return;

        var leftBlock = Block.getBlock(block.pointX - 1,block.pointY);

        if(leftBlock){

            leftBlock.pointX = block.pointX;

            leftBlock.setPosition(block.pointX*60,block.pointY*60+30);

            leftBlock.checkTheSame();

        }

        block.pointX --;

        block.setPosition(block.pointX*60,block.pointY*60+30);

        block.checkTheSame();

    },

    moveRight:function(block){

        if(block.pointX == LLK.LEVEL.x - 1)return;

        var rightBlock = Block.getBlock(block.pointX + 1,block.pointY);

        if(rightBlock){

            rightBlock.pointX = block.pointX;

            rightBlock.setPosition(block.pointX*60,block.pointY*60+30);

            rightBlock.checkTheSame();

        }

        block.pointX ++;

        block.setPosition(block.pointX*60,block.pointY*60+30);

        block.checkTheSame();

    },

    moveUp:function(block){

        if(block.pointY == LLK.LEVEL.y - 1)return;

        var upBlock = Block.getBlock(block.pointX,block.pointY+1);

        if(upBlock){

            upBlock.pointY = block.pointY;

            upBlock.setAnchorPoint(cc.p(0, 0));

            upBlock.setPosition(block.pointX*60,block.pointY*60+30);

            upBlock.checkTheSame();

        }

        block.pointY ++;

        block.setPosition(block.pointX*60,block.pointY*60+30);

        block.checkTheSame();

    },

    moveDown:function(block){

        if(block.pointY == 0)return;

        var downBlock = Block.getBlock(block.pointX,block.pointY - 1);

        if(downBlock){

            downBlock.pointY = block.pointY;

            downBlock.setPosition(block.pointX*60,block.pointY*60+30);

            downBlock.checkTheSame();

        }

        block.pointY --;

//        block.setAnchorPoint(cc.p(0, 0));

        block.setPosition(block.pointX*60,block.pointY*60+30);

        block.checkTheSame();

    },

    checkTheSame:function(){

        this.checkLeft() || this.checkUp()||this.checkRight()||this.checkDown();

    },

    checkLeft:function(){

        if(this.pointX == 0)return false;

        var leftBlock = Block.getBlock(this.pointX - 1,this.pointY);

        if(leftBlock && leftBlock.name == this.name){

            this.destroy();

            leftBlock.destroy();

            return true;

        }

        return false;

    },

    checkRight:function(){

        if(this.pointX == LLK.LEVEL.x - 1)return false;

        var rightBlock = Block.getBlock(this.pointX + 1,this.pointY);

        if(rightBlock && rightBlock.name == this.name){

            this.destroy();

            rightBlock.destroy();

            return true;

        }

        return false;

    },

    checkUp:function(){

        if(this.pointY == LLK.LEVEL.y - 1)return false;

        var upBlock = Block.getBlock(this.pointX,this.pointY+1);

        if(upBlock && upBlock.name == this.name){

            this.destroy();

            upBlock.destroy();

            return true;

        }

        return false;

    },

    checkDown:function(){

        if(this.pointY == 0)return false;

        var downBlock = Block.getBlock(this.pointX,this.pointY - 1);

        if(downBlock && downBlock.name == this.name){

            this.destroy();

            downBlock.destroy();

            return true;

        }

        return false;

    }

 

});

 

Block.getBlock = function(pointX,pointY) {

  for (var j = 0,len = LLK.map.length; j < len; j++) {

    if (LLK.map[j].active && pointX == LLK.map[j].pointX && pointY == LLK.map[j].pointY)

    {

      return LLK.map[j];

    }

  }

  return null;

};
  首先我们先来看Block的几个重要属性: name是block的名字属性,用来判断相邻的block是不是同种类型, active是block是否存在界面上的标识, pointX, pointY是block的位置坐标。
接下来我们看构造方法 ctor
ctor:function (arg) {

        this._super();

        if(!arg)return;

        this.initWithSpriteFrameName(arg);

        this.name = arg;

//        cc.registerTargetedDelegate(0,true,this);

        cc.Director.getInstance().getTouchDispatcher().addTargetedDelegate(this, 0, true);

    },

  构造方法中,使用initWithSpriteFrameName方法根据传进来的参数初始化sprite,同时,给sprite的name属性赋值,之后添加该sprite的触摸监听事件。

  接下来看getBlock这个方法,它根据传入的坐标位置获取相对应的block,而获取的这个block前提是它的active属性为true,也就是获取到的是还存在界面上的block,不存在的话就返回null。
Block.getBlock = function(pointX,pointY) {

  for (var j = 0,len = LLK.map.length; j < len; j++) {

    if (LLK.map[j].active && pointX == LLK.map[j].pointX && pointY == LLK.map[j].pointY)

    {

      return LLK.map[j];

    }

  }

  return null;

};
  onTouchBegan、 onTouchMoved、 onTouchEnded是对触摸事件的相应,在 onTouchBegan和 onTouchMoved中,我们需要先行判断当前的触点是否存在与sprite上,所有我们有了 containsTouchLocation这个方法  ,在刚触摸的瞬间我们把sprite放大并且把当前的flash标识设置为true,这个flash标识是用来判断我们的触摸拖动是否已经结束(其实也应该可以不用这么做,但是我在调试中发现了个bug,所以就设置了这个标识),而在 onTouchMoved中,我们根据拖动的位移判断当前是往那个方向移动,然后移动Block。移动结束后,我们在 onTouchEnded把Block的大小还原。
 
    //判断触摸点是否在图片的区域上

    containsTouchLocation:function (touch) {

        //获取触摸点位置

        var getPoint = touch.getLocation();

 

        //物体当前区域所在的位置

        var contentSize  =  this.getContentSize();

        var myRect = cc.rect(0, 0, contentSize.width, contentSize.height);

        myRect.origin.x += this.getPosition().x;

        myRect.origin.y += this.getPosition().y;

        //判断点击是否在区域上

        return cc.rectContainsPoint(myRect,getPoint);

    },

    //刚触摸瞬间

    onTouchBegan:function (touch, event) {

        if (!this.containsTouchLocation(touch)) return false;

        this.beginPoint = touch.getLocation();

//        this.setZIndex(100);

        this.flash = true;

        this.setScale(1.2);

        return true;

    },

    //触摸移动

    onTouchMoved:function (touch, event) {

        if (!this.containsTouchLocation(touch)) return false;

        var touchPoint = touch.getLocation();

        var xDist = touchPoint.x - this.beginPoint.x,yDist = touchPoint.y - this.beginPoint.y;

        //移动距离超过10个像素位才有效

        if((Math.abs(xDist) >= 10 || Math.abs(yDist) >= 10)&&this.flash){

            this.flash = false;

            var block = this;

            if(Math.abs(xDist) > Math.abs(yDist)){

                if(xDist > 0){this.moveRight(block);}

                else{this.moveLeft(block);}

            }

            else{

                if(yDist > 0){this.moveUp(block);}

                else{this.moveDown(block);}

            }

            return false;

        }

    },

    onTouchEnded:function(touch,event){

        this.setScale(1);

        this.flash = true;

    },
  而在我们移动方块后,我们需要判断发生位移的方块是否在上下左右4个方向上存在相同的方块,这个通过 checkTheSame来实现,具体看源码
checkTheSame:function(){

        this.checkLeft() || this.checkUp()||this.checkRight()||this.checkDown();

},
之后是相同的方块销毁隐藏
//销毁隐藏

    destroy:function () {

        var explosion =Explosion.getOrCreateExplosion();

        explosion.setPosition(this.getPosition());

//        SparkEffect.getOrCreateSparkEffect(this.getPosition());

        if(LLK.SOUND){

            cc.AudioEngine.getInstance().setMusicVolume(0.7);

            cc.AudioEngine.getInstance().playEffect(s_explodeEffect_mp3);

        }

     this.setVisible(false);

        this.active = false;

        LLK.COUNT --;

        if(LLK.COUNT <= 0/* || 1*/){

            g_sharedGameLayer.onGameOver();

        }

    },
在该方法中,我们隐藏Block并且在Block的位置添加爆炸效果然后播放音效,之后,我们的Block总计数减1,然后在计数为0的时候游戏结束,调用主程序的onGameOver方法结束游戏。
 
 

你可能感兴趣的:(cocos2d-html5)