用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方法结束游戏。
 
 
posted @ 2014-06-10 09:22  jackyWHJ  阅读(1607)  评论(1编辑  收藏  举报