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 幻灯片的实现
Dec 06 Javascript
纯js分页代码(简洁实用)
Nov 05 Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
Mar 02 Javascript
异步JavaScript编程中的Promise使用方法
Jul 28 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
Aug 06 Javascript
js实现控制textarea输入字符串的个数,鼠标按下抬起判断输入字符数
Oct 25 Javascript
浅谈vue的iview列表table render函数设置DOM属性值的方法
Sep 30 Javascript
iview日期控件,双向绑定日期格式的方法
Mar 15 Javascript
JavaScript设计模式之享元模式实例详解
Jan 17 Javascript
element-ui 文件上传修改文件名的方法示例
Nov 05 Javascript
vuex中store存储store.commit和store.dispatch的用法
Jul 24 Javascript
jQuery实现可以计算进制转换的计算器
Oct 19 jQuery
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中使用模板的方法
2008/05/24 PHP
php创建多级目录代码
2008/06/05 PHP
PHP之预定义接口详解
2015/07/29 PHP
ko knockoutjs动态属性绑定技巧应用
2012/11/14 Javascript
jquery.messager.js插件导致页面抖动的解决方法
2013/07/14 Javascript
js实现的点击数量加一可操作数据库
2014/05/09 Javascript
js从Cookies里面取值的简单实现
2014/06/30 Javascript
js倒计时简单实现方法
2015/12/17 Javascript
node.js 中国天气预报 简单实现
2016/06/06 Javascript
Bootstrap零基础入门教程(二)
2016/07/18 Javascript
jQuery实现页面点击后退弹出提示框的方法
2016/08/24 Javascript
jquery仿京东商品放大浏览页面
2017/06/06 jQuery
关于react-router的几种配置方式详解
2017/07/24 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
浅谈react性能优化的方法
2018/09/05 Javascript
vue-cli+axios实现文件上传下载功能(下载接收后台返回文件流)
2019/05/10 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
JS实现公告上线滚动效果
2021/01/10 Javascript
python连接mongodb操作数据示例(mongodb数据库配置类)
2013/12/31 Python
pip 错误unused-command-line-argument-hard-error-in-future解决办法
2014/06/01 Python
Python出现segfault错误解决方法
2016/04/16 Python
python实现简单flappy bird
2018/12/24 Python
Appium+Python自动化测试之运行App程序示例
2019/01/23 Python
Python制作exe文件简单流程
2019/01/24 Python
Python while循环使用else语句代码实例
2020/02/07 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
2020/10/23 Python
css3 position fixed固定居中问题解决方案
2014/08/19 HTML / CSS
斯洛伐克电子产品购物网站:DATART
2020/04/05 全球购物
给校长的建议书600字
2014/05/15 职场文书
消防安全宣传标语
2014/06/07 职场文书
银行会计主管岗位职责
2014/10/01 职场文书
2014年工程师工作总结
2014/11/25 职场文书
开学随笔
2015/08/15 职场文书
小学生大队委竞选稿
2015/11/20 职场文书
PyTorch 如何检查模型梯度是否可导
2021/06/05 Python
Redis中缓存穿透/击穿/雪崩问题和解决方法
2021/12/04 Redis