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:打开
代码注释