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


Posted in Javascript onJuly 07, 2015

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

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

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

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

游戏截图PC端:

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

游戏截图移动端:

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

模板引擎用了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:打开

Javascript 相关文章推荐
srcElement表格样式
Sep 03 Javascript
js 复制或插入Html的实现方法小结
May 19 Javascript
javascript工具库代码
Mar 29 Javascript
Javascript中Array.prototype.map()详解
Oct 22 Javascript
jquery中animate的stop()方法作用实例分析
Jan 30 Javascript
jquery分割字符串的方法
Jun 24 Javascript
如何高效率去掉js数组中的重复项
Apr 12 Javascript
jquery文字填写自动高度的实现方法
Nov 07 Javascript
JS实现鼠标移上去显示图片或微信二维码
Dec 14 Javascript
js从输入框读取内容,比较两个数字的大小方法
Mar 13 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
Aug 07 Javascript
深入浅析React中diff算法
May 19 Javascript
javascript实现控制div颜色
Jul 07 #Javascript
浅谈JavaScript中的字符编码转换问题
Jul 07 #Javascript
JavaScript中判断两个字符串是否相等的方法
Jul 07 #Javascript
javascript中数组方法汇总
Jul 07 #Javascript
jQuery原型属性和原型方法详解
Jul 07 #Javascript
在JavaScript中访问字符串的子串
Jul 07 #Javascript
jQuery.each使用详解
Jul 07 #Javascript
You might like
php读取文件内容的几种方法详解
2013/06/26 PHP
php函数与传递参数实例分析
2014/11/15 PHP
PHP实现上一篇下一篇的方法实例总结
2016/09/22 PHP
php 生成签名及验证签名详解
2016/10/26 PHP
浅谈PHP的反射机制
2016/12/15 PHP
PHP实现类似题库抽题效果
2018/08/16 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
JavaScript中的new的使用方法与注意事项
2007/05/16 Javascript
js实现的切换面板实例代码
2013/06/17 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
jQuery实现简单滚动动画效果
2016/04/07 Javascript
详解Backbone.js框架中的模型Model与其集合collection
2016/05/05 Javascript
JS封装的选项卡TAB切换效果示例
2016/09/20 Javascript
Express框架之connect-flash详解
2017/05/31 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
vue实现树状表格效果
2020/12/29 Vue.js
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
Python Socket使用实例
2017/12/18 Python
python实现朴素贝叶斯算法
2018/11/19 Python
通过shell+python实现企业微信预警
2019/03/07 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
2019/07/22 Python
python os.fork() 循环输出方法
2019/08/08 Python
Django结合ajax进行页面实时更新的例子
2019/08/12 Python
Python 实现黑客帝国中的字符雨的示例代码
2020/02/20 Python
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
外贸业务员工作职责
2014/01/06 职场文书
关于运动会的广播稿
2014/09/22 职场文书
标准单位租车协议书
2014/09/23 职场文书
镇党政领导班子民主生活会思想汇报
2014/10/11 职场文书
聘任证明怎么写
2015/03/02 职场文书
肖申克的救赎观后感
2015/06/02 职场文书
父母教会我观后感
2015/06/17 职场文书
Nginx解决前端访问资源跨域问题的方法详解
2021/03/31 Servers
Python基础之操作MySQL数据库
2021/05/06 Python
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
小程序实现文字循环滚动动画
2021/06/14 Javascript