zoukankan      html  css  js  c++  java
  • 用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方法结束游戏。
     
     
  • 相关阅读:
    高精度计算
    c++ sort
    算法分类小结
    二叉树层序遍历
    clion windows c++环境配置 mingw
    kafka,filebeat 配置
    centos7 源码安装mysql5.7
    如何优雅的生成及遍历python嵌套字典
    Java Swing 绝对布局管理方法,null布局【图】
    python3.4+pymssql 中文乱码问题解决
  • 原文地址:https://www.cnblogs.com/jackyWHJ/p/3778270.html
Copyright © 2011-2022 走看看