俄羅斯方塊這個遊戲也做了移動端的兼容, 這個遊戲難點是怎麼翻轉方塊, 自己實現的方式是把方塊放到一個二維數組, 然後逆時針旋轉二維數組。
也有別的方法,例如直接用一個全域變數代表一個方向, 翻轉的時候根據這個變數轉動方塊, 但是程式碼要寫更多。
在文庫搜尋到了一篇關於演算法的文章, ....看著好心塞:
遊戲截圖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:開啟