Javascript编写俄罗斯方块思路及实例

前端技术 2023/09/09 JavaScript

  俄罗斯方块这个游戏也做了移动端的兼容, 这个游戏难点是怎么翻转方块, 自己实现的方式是把方块放到一个二维数组, 然后逆时针旋转二维数组。

  也有别的方法,比如直接用一个全局变量代表一个方向, 翻转的时候根据这个变量转动方块, 但是代码要写更多。

  在文库搜索到了一篇关于算法的文章, ....看着好心塞:

  游戏截图PC端:

  游戏截图移动端:

  模板引擎用了HandlebarsJS,  为了更好的模块化,也用了requireJS....没用好;

运行下面代码

var cfg = {
  width:14,
  height:20,
  time : 400
};
requirejs.config({
  baseUrl: \'libs\',
  paths: {
    app: \'../app\'
  }
});

requirejs([\"app/controller/mainController\",\"app/view/mobileDOM\",\"app/util\"], function(con, mobileDOM, util) {

  if(util.isMobile()) {
    mobileDOM.addDOM();
  };
  con();
});

  游戏主要有三个模型层: 游戏方块的模型层, 游戏分数的模型层, 游戏整体界面结构模型层;

  控制层就一个, 就是用户点击游戏开始的按钮, 游戏就开始了, 如果是PC,就会监听keydown事件, 如果是移动端, 就新建四个方向键的DOM, 监听方向键的点击事件,事件会使当前方块的数据模型发生旋转, 至于显示,那是view层的事情,先不用管, 主要的逻辑包括方块的随机生成, 方块的碰撞检测,方块的消除,分数的增加, 重新随机生成方块等:

运行下面代码

define([\"app/util\"],function(util) {
  //分数模块,游戏开始的时候会用到;
  var score = {};
  require([\"app/model/score\"],function(defineScore) {
    score = defineScore;
  });

  var startGame = function() {
    //把当前的input元素禁用;
    $(this).attr(\"disabled\",\"true\");
    requirejs([\"app/model/data\",\"app/view/init\",\"app/model/Block\"], function(data, view, Block){
      //初始化方块;
      var block = new Block;
      var mapData = {};

      //方块发生改变的时候,我们用回调重新渲染界面;
      block.onupdate( function() {
        var blockData = this.get();
        //把数据格式转化成map数据;
        mapData = data.extend(blockData);
        $(\"#table\").html( view( mapData ) );
      });

      block.testTouch = data.testTouch;

      //如果元素触底了或者是元素已经被卡主不能动的情况下;
      block.onend(function() {
        //这个说明当前的block触底了
        data.set( mapData );
        //我们需要重新生成一个方块, 直接调用newBlock即可;
        block.newBlock();
        //通过data计算,如果有连接起来的一条线,就执行SCORE回调, 随之会更新当前界面的分值;
        //如果方块跑到了最上面就是游戏失败了;
        data.oncalculate( score.addScore , block.destory.bind(block));
      });

      //现在才开始绑定事件
      if(!util.isMobile()) {
        $(window).keydown(function(ev) {
          if(ev.keyCode === 37) {
            block.add(block.moveLeft,\"left\");
          }else if( ev.keyCode === 39 ) {
            block.add(block.moveRight,\"right\");
          }else if( ev.keyCode === 40 ) {
            block.add(block.moveDown,\"down\");
          }else if( ev.keyCode === 38 ) {
            block.rotate();
          };
        });
      }else{
        $(\".arrow-up\").tap(function() {
          block.rotate();
        });
        $(\".arrow-down\").tap(function() {
          block.add(block.moveDown,\"down\");
        });
        $(\".arrow-left\").tap(function() {
          block.add(block.moveLeft,\"left\");
        });
        $(\".arrow-right\").tap(function() {
          block.add(block.moveRight,\"right\");
        });
      };
    });
  };

  //绑定界面事件 ,keyDown;
  var bindEvent = function() {
    //start....
    $(\"#start\").click(startGame)
  };
  //为移动端添加DOM节点,
  //然后绑定移动端的事件;

  return function() {
    bindEvent();
  };
});

  游戏的主要窗口直接看成是二维数组, 所有要显示的方块都是数组中的数据, 通过模板引擎, 一秒钟更新一次data到view, 模板如下:

运行下面代码

  <script type=\"text/x-handlebars-template\" id=\"tpl-td\">
    {{#each this}}
      <tr>
        {{#each this}}
          <td class=\"{{#if this}}block{{/if}}\">
          </td>
        {{/each}}
      </tr>
    {{/each}}
  </script>

  为了让整体的内容和提示更加美观,用了提示插件 zepto.alert和bootStrap;

  在线DEMO:打开

本文地址:https://www.stayed.cn/item/23912

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。