테트리스 게임은 모바일 단말기와도 호환됩니다. 블록을 뒤집는 방법이 제가 구현한 방식은 블록을 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(); });
게임에는 주로 게임 블록의 모델 레이어, 게임 점수의 모델 레이어, 전체 게임 인터페이스 구조 모델 레이어의 세 가지 모델 레이어가 있습니다.
컨트롤 레이어는 하나뿐입니다. 즉, 사용자가 게임 시작 버튼을 클릭하면 게임이 시작됩니다. PC인 경우에는 keydown 이벤트를 수신합니다. 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(); }; });
게임의 메인 창은 2차원 배열로 바로 보여지며, 표시되는 모든 블록은 템플릿 엔진을 통해 1초에 한번씩 뷰에 업데이트됩니다. 다음과 같습니다:
다음 코드를 실행하세요
<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이 사용됩니다.
온라인 데모: 공개