HTML5 Canvas消除游戏

玩过微信“天天爱消除”游戏的人都应该了解这类游戏,尤其这类游戏常常受到许多妹子的喜欢,所以我还是花了周末一天的时间做做这个游戏。

我的这个游戏当然没有微信里的效果那么炫酷,只是完成了消除游戏一些核心的逻辑,包括消失、补全、交换这些。

仔细算下来,这好像已经是我的第7款小游戏了,这又让我开始憧憬大游戏的到来。

算了,反正小时候玩过那么多小游戏,先把那些记忆中的游戏写完再说。

这款游戏还是延续canvas的方案,主要的逻辑还是在判断消失和补全的部分,

核心代码如下:

[code]
/**
     * 检查下落补缺的方块
     */
    checkDropBlock: function() {
      var len = 0, hasFade = false;
      for(var i = 0; i < span.x; i++) {
        hasFade = false;
        for(var j = span.y - 1; j >= 0; j--) {
          var m = matrix[j][i];
          if(!hasFade && m.opacity <= 0) {
            //垂直方向从下往上找,当找到第一个消失的方块时记录位置,
            //后面就不用再记录了
            hasFade = true;
            len = j;
          } else if(hasFade && m.opacity > 0) {
            //遇到有效的方块则往下移动
            matrix[len][i] = this.clone(m);
            matrix[j][i].opacity = 0;
            len--;
          }
          //当到达最顶部时,不够的选择随机的方块补充上,以此填满
          if(j === 0 && m.opacity <= 0) {
            while(len >= 0) {
              matrix[len][i] = this.getRandomBlock();
              len--;
            }
          }
        }
      }
    }
 /**
     * 检查需要消失渐变的方块
     * @param x 结束的x坐标
     * @param y 结束的y坐标
     * @param len 消失方块连续长度
     * @param direct 方向
     * @returns {boolean} true-有消失的,false-无消失的
     */
    checkFadeBlock: function(x, y, len, direct) {
      if(len >= 3) {
        //长度大于等于3才会消失
        while(len > 0) {
          var m = direct === 'x' ? matrix[y][x-len] : matrix[y-len][x];
          //依次往前排,打上tag
          m.fade = 1;
          len--;
        }
        return true;
      }
      return false;
    },
    /**
     * 检测两个方块是否相邻
     * @param x1 方块1x坐标
     * @param y1 方块1y坐标
     * @param x2 方块2x坐标
     * @param y2 方块2y坐标
     * @returns {boolean} true-相邻,false-不相邻
     */
    checkNearBlock: function(x1, y1 ,x2 ,y2) {
      return (x1 - x2 === 1 && y1 - y2 === 0)
        || (x1 - x2 === -1 && y1 - y2 === 0)
        || (x1 - x2 === 0 && y1 - y2 === 1)
        || (x1 - x2 === 0 && y1 - y2 === -1);
    },
    /**
     * 全局检查是否有3个及3个以上连续相同的方块
     * @returns {boolean} true-有,false-没有
     */
    checkSameBlock: function() {
      var len = 0, color, opacity, ret = false;
      for(var i = 0; i < span.y; i++) {
        len = 0;
        //从左边第一个开始标记
        color = matrix[i][0].color;
        opacity = matrix[i][0].opacity;
        for(var j = 0; j < span.x; j++) {
          var m = matrix[i][j];
          if(m.opacity > 0 && opacity > 0 && m.color === color) {
            //如果方块有效,并且颜色等于上个方块的颜色,则len加1
            len++;
            if(j === span.x-1 && this.checkFadeBlock(j+1, i, len, 'x')) {
              //最右边时直接检查
              ret = true;
            }
          } else {
            //如果满足消失的要求在打上tag
            if(this.checkFadeBlock(j, i, len, 'x')) {
              ret = true;
            }
            //如果一旦出现无效或者颜色不等于上个方块的颜色,则充值len和颜色
            len = 1;
            color = m.color;
            opacity = m.opacity;
          }
        }
      }
      //同上
      for(i = 0; i < span.x; i++) {
        len = 0;
        color = matrix[0][i].color;
        opacity = matrix[0][i].opacity;
        for(j = 0; j < span.y; j++) {
          var mm = matrix[j][i];
          if(mm.opacity > 0 && opacity > 0 && mm.color === color) {
            len++;
            if(j === span.y-1 && this.checkFadeBlock(i, j+1, len, 'y')) {
              ret = true;
            }
          } else {
            if(this.checkFadeBlock(i, j, len, 'y')) {
              ret = true;
            }
            len = 1;
            color = mm.color;
            opacity = mm.opacity;
          }
        }
      }
      if(ret && !animating) {
        //如果满足条件并且不处于动画中,则开启渐变消失动画
        animating = true;
        this.createFadeBlock();
      }
      return ret;
    }
/**
     * 创建渐变消失动画
     */
    createFadeBlock: function() {
      fadeTimer && clearTimeout(fadeTimer);
      var flag = false;
      for(var i = 0; i < span.y; i++) {
        for(var j = 0; j < span.x; j++) {
          var m = matrix[i][j];
          if(m.fade === 1) {
            //标记消失的才执行动画
            flag = true;
            m.opacity -= 0.1;
            if(m.opacity <= 0) {
              //完全透明了了则可以结束动画了
              m.fade = 0;
              m.opacity = 0;
              m.color = Color.bg;
              flag = false;
            }
          }
        }
      }
      if(flag) {
        fadeTimer = setTimeout(function() {
          elimination.createFadeBlock();
        }, 10);
      } else {
        fadeTimer && clearTimeout(fadeTimer);
        animating = false;
        //随时都要检查是否要补齐空缺的方块
        this.checkDropBlock();
        //检查相同的方块
        this.checkSameBlock();
      }
    }
/**
     * 开始后的点击事件回调
     * @param e
     */
    startedClickHandler: function(e) {
      var x = e.offsetX,
        y = e.offsetY,
        size = Config.size;
      x = Math.floor(x / size);
      y = Math.floor(y / size);
      var m = matrix[y][x];
      if(m.selected === 0) {
        //未有选中状态
        for(var i = 0; i < span.y; i++) {
          for (var j = 0; j < span.x; j++) {
            var mm = matrix[i][j];
            if(mm.selected === 1 && this.checkNearBlock(x, y, j, i)) {
              //如果两个方块都被选中并且相邻才交换眼色
              var color = mm.color;
              mm.color = m.color;
              m.color = color;
              if(!this.checkSameBlock()) {
                //如果交换没有消失的方块,则不能交换,直接还原
                var tColor = mm.color;
                mm.color = m.color;
                m.color = tColor;
              }
            }
            mm.selected = +(i === y && j === x);
          }
        }
      } else {
        //已选中的话则去掉选中状态
        m.selected = 0;
      }
    }
[/code]

demos地址是:http://xiechengxiong.com/xui/demos/elimination/ (只能在手机上玩哦)
扫扫更健康:20141020171334

 

别忘了光顾我的博客首页:http://xiechengxiong.com/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值