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 相关文章推荐
js异常捕获方法介绍
Apr 10 Javascript
阻止子元素继承父元素事件具体思路及实现
May 02 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
Jul 07 Javascript
jquery.form.js用法之清空form的方法
Mar 07 Javascript
javascript的创建多行字符串的7种方法
Apr 29 Javascript
JavaScript动态加载样式表的方法
Mar 21 Javascript
Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
Jul 01 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
Aug 26 Javascript
node.js缺少mysql模块运行报错的解决方法
Nov 13 Javascript
详解Angular2 关于*ngFor 嵌套循环
May 22 Javascript
JavaScript类数组对象转换为数组对象的方法实例分析
Jul 24 Javascript
详解操作虚拟dom模拟react视图渲染
Jul 25 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导出MySQL数据到Excel文件(fputcsv)
2011/07/03 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
2013/07/01 PHP
php中curl、fsocket、file_get_content三个函数的使用比较
2014/05/09 PHP
PHP写日志的实现方法
2014/11/05 PHP
PHP获取数组中重复最多的元素的实现方法
2014/11/11 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
2015/03/19 PHP
JSON 入门指南 想了解json的朋友可以看下
2009/08/26 Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
2010/07/29 Javascript
JQuery获取文本框中字符长度的代码
2011/09/29 Javascript
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
2014/05/20 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
AngularJS实现DOM元素的显示与隐藏功能
2016/11/22 Javascript
详解用webpack2搭建angular2的项目
2017/06/22 Javascript
基于vue.js中事件修饰符.self的用法(详解)
2018/02/23 Javascript
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
Python抽象类的新写法
2015/06/18 Python
深入理解python try异常处理机制
2016/06/01 Python
Python列表切片用法示例
2017/04/19 Python
Django 连接sql server数据库的方法
2018/06/30 Python
Pandas聚合运算和分组运算的实现示例
2019/10/17 Python
python 统计文件中的字符串数目示例
2019/12/24 Python
Python捕获异常堆栈信息的几种方法(小结)
2020/05/18 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
2020/06/23 Python
selenium学习教程之定位以及切换frame(iframe)
2021/01/04 Python
手对手的教你用canvas画一个简单的海报的方法示例
2018/12/10 HTML / CSS
美国最受欢迎的度假目的地优惠套餐:BookVIP
2018/09/27 全球购物
Cinque网上商店:德国服装品牌
2019/03/17 全球购物
前台接待岗位职责
2013/12/03 职场文书
公司廉洁自律承诺书
2014/03/27 职场文书
高中家长寄语
2014/04/02 职场文书
欢迎家长标语
2014/10/08 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
mysql timestamp比较查询遇到的坑及解决
2021/11/27 MySQL