テトリスというゲームはモバイル端末にも対応しています。このゲームの難しいところは、ブロックを 2 次元配列に配置し、その 2 次元配列を回転させる方法です。反時計回り。
他にも、グローバル変数を直接使って方向を表現したり、反転する際にその変数に従ってブロックを回転させたりする方法もありますが、さらにコードを書く必要があります。
図書館でアルゴリズムに関する記事を探しました...。とても悲しそうな顔をしていました:
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(); });
ゲームには主に 3 つのモデル層があります。ゲーム ブロックのモデル層、ゲーム スコアのモデル層、ゲーム インターフェイス全体の構造モデル層です。
コントロール層は 1 つだけです。つまり、ユーザーがゲーム開始ボタンをクリックすると、PC の場合はキーダウン イベントが開始されます。モバイル端末の場合は、キーダウン イベントが開始されます。 4 方向キーの DOM を作成し、方向キーのクリックをリッスンします。イベントにより、現在のブロックのデータ モデルが回転します。表示に関しては、ビュー レイヤーの問題です。今のところは心配する必要はありません。メイン ロジックには、ブロックのランダム生成、ブロックの衝突検出、ブロックの削除、スコアの増加、ブロックの再ランダム生成などが含まれます。
次のコードを実行します
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(); }; });
次のコードを実行します
<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>
オンラインデモ:
開く