cococos 2 d-html 5で作った消去ゲーム『ヒーロー愛消去』(2)——Blockデザイン実現

28979 ワード

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識別子はタッチドラッグが終了したかどうかを判断するために使用されます(実際にはそうしなくてもいいはずですが、デバッグでバグを見つけたので、この識別子を設定しました).
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メソッドを呼び出してゲームを終了します.
 
 
次はいくつかの主な機能のチュートリアルです.
cococos 2 d-html 5で作った消去ゲーム「英雄愛消去」——概要
cococos 2 d-html 5で作った消去ゲーム『ヒーロー愛消去』(1)——システムメインメニュー
cococos 2 d-html 5で作った消去ゲーム『ヒーロー愛消去』(2)——Blockデザイン実現
cococos 2 d-html 5で作った消去系ゲーム『英雄愛消去』(3)——ゲームメインインタフェース
cococos 2 d-html 5で作った消去系ゲーム『ヒーロー愛消去』(4)——ゲーム終了
 
ps:概要に完全なソースリンクがあります