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 相关文章推荐
javascript attachEvent和addEventListener使用方法
Mar 19 Javascript
在IE6下发生Internet Explorer cannot open the Internet site错误
Jun 21 Javascript
jQuery实现点击图片翻页展示效果的方法
Feb 16 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
Oct 12 Javascript
JS中from 表单序列化提交的代码
Jan 20 Javascript
javascript实现下雨效果
Mar 27 Javascript
jQuery实现所有验证通过方可提交的表单验证
Nov 21 jQuery
vue-resource请求实现http登录拦截或者路由拦截的方法
Jul 11 Javascript
jQuery轮播图实例详解
Aug 15 jQuery
Vue在页面数据渲染完成之后的调用方法
Sep 11 Javascript
vue.js实现回到顶部动画效果
Jul 31 Javascript
vue倒计时刷新页面不会从头开始的解决方法
Mar 03 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
Laravel框架实现修改登录和注册接口数据返回格式的方法
2018/08/17 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
js文字滚动停顿效果代码
2008/06/28 Javascript
读jQuery之四(优雅的迭代)
2011/06/20 Javascript
js中的referrer返回上一页使用介绍
2013/09/26 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
2014/12/28 Javascript
原生js和jquery实现图片轮播淡入淡出效果
2015/04/23 Javascript
使用Raygun对Node.js应用进行错误处理的方法
2015/06/23 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
浅谈react+es6+webpack的基础配置
2017/08/09 Javascript
JS实现瀑布流布局
2017/10/21 Javascript
基于vue1和vue2获取dom元素的方法
2018/03/17 Javascript
JS实现同一DOM元素上onClick事件与onDblClick事件并存的解决方法
2018/06/07 Javascript
jQuery实现ajax回调函数带入参数的方法示例
2018/06/26 jQuery
详解angularjs跨页面传参遇到的一些问题
2018/11/01 Javascript
JS实现的图片选择顺序切换和循环切换功能示例【测试可用】
2018/12/28 Javascript
Bootstrap4 gulp 配置详解
2019/01/06 Javascript
js正则表达式简单校验方法
2021/01/03 Javascript
[01:34:42]NAVI vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
零基础写python爬虫之爬虫编写全记录
2014/11/06 Python
使用Python将数组的元素导出到变量中(unpacking)
2016/10/27 Python
python如何爬取网站数据并进行数据可视化
2019/07/08 Python
Python通过队列来实现进程间通信的示例
2020/10/14 Python
Python Spyder 调出缩进对齐线的操作
2021/02/26 Python
英国顶级珠宝品牌之家:John Greed
2018/06/09 全球购物
幼儿教师自我鉴定
2013/11/02 职场文书
小学开学典礼主持词
2014/03/19 职场文书
护理专业毕业生自荐信
2014/06/15 职场文书
个人批评与自我批评发言稿
2014/09/28 职场文书
周年庆典答谢词
2015/01/20 职场文书
2015年幼儿园中班工作总结
2015/04/25 职场文书
MySql新手入门的基本操作汇总
2021/05/13 MySQL
Requests什么的通通爬不了的Python超强反爬虫方案!
2021/05/20 Python
python用tkinter开发的扫雷游戏
2021/06/01 Python