zoukankan      html  css  js  c++  java
  • JS/Jquery版本的俄罗斯方块(附源码分析)

    转载于 http://blog.csdn.net/unionline/article/details/63250597 且后续更新于此

    1.前言

    写这个jQuery版本的小游戏的缘由在于我想通过从零到有,自己写一个Jquery版本的游戏用来练手,没参考过其他人代码,这样子才不会影响自己的思路。

    经历了V1,V2版本,当前版本是V3,版本说明如下:

    V1: Use two methods of left and right conflict check, bottom conflict check.
    V2: Use U style conflict check for left and right and bottom.
    V2.1: add keyDownRaip when press v_down key.
    V2.0.2:add Debug Zone for test and theft operation based V2.
    V3:UI adjust for lj.w based V2.0.2
    V3.1:Add function of Pageviews and Leaderboard.
    V4.0:Add function of auto adjust UI

    /*****************************************************************/

    JS/Jquery版本的俄罗斯方块(Tetris)V4.0
    作者: unionline
    邮箱:zplufb@163.com
    转载请说明来自: http://blog.csdn.net/unionline
     
    /*****************************************************************/

    2.游戏说明

    功能:关卡,分数,暂停,虚拟键,状态栏,自定义宽高大小,还有金手指。
    在线试玩地址:play online
    游戏界面如下:

     

    3.难点及开发时遇到的问题汇总

    1.碰撞检测和模型设计
    答:在V1版本由于设计模型不合理导致碰撞检测不完美,而且得付出更多代价,后面改成了U模型。
     
    2.当cube下降到底部,该给予短时间移动方块(符合游戏玩法)
    答:给setTimeout,并延迟刷新二维数据
     
    3.方块旋转
    答:详情请见KeyHanderUp方法
     
    4.触发下一个cube
    答:之前用定时器刷新,后来改为当碰到下边界,触发Next();
     
    5.下降碰到边界向左或向右移动,此时该cube下面为可降落
    答:详情请见KeyHanderDown方法
     
    6. to be continued ...

    4.源码分析

    方法说明:
    InitUI(): 初始化界面,绘制出UI
    InitData():初始化所有参数
    InitVK():初始化并绑定button的响应事件
     
    InitAllCubeStatusArr:初始化二维矩阵
    printAllCubeStatusArr:打印二维矩阵,在console打印
    UpdateAllCubeStatusArr:更新二维矩阵
     
    RefreshDrawUI:重绘左侧主区UI
    CheckRemoveRowInline:判定是否为可以删除行
    RemoveRowInline:删除指定行
    UpdateScore:更新分数
    UpdateLevel:更新关卡
    CheckGameOver:判定是否Game Over
    TextSatutsTimeOut:右下角状态栏显示秒数和内容
    Int:取整操作
     
    CheckNextStatusIsBoundary:判定是否到达边界
    CubeInBlock:碰撞检测的核心代码
    Types:俄罗斯方块的7中类型
    KeyHanderUp/KeyHanderDown/KeyHanderLeft/KeyHanderRight:上下左右操作
    UpdatePosNextStatus:更新下一个位置的状态位,为边界判定服务。
     
    showCurTypeInMainBoard:显示当前的方块
    GetRandType:获取随机数,从而获得下一个候选区的方块
    ShowCandidateType:显示候选区方块
     
    DrawMainUI:绘制左侧主区UI
    DrawCandidateZoneUI:绘制候选区主区UI
    DrawOperationZoneUI:绘制操作区UI
    Start:获取候选区方块
    Next:下一个方块降落
    Play:点击play按钮触发,点击后变成pause,可以暂停游戏
     
    Pageviews and Leaderboard的源码,请到在线游戏处查看

    5.源码(V3版本)

       1 <!DOCTYPE html>
       2 <html>
       3 <head>
       4 <meta chatset="utf-8">
       5 <title>Unionline's JS Tetris V3</title>
       6 <script src="https://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
       7 <style>
       8 
       9 table{
      10 border: 1px solid #f77;
      11 }
      12 
      13 td{
      14     border: 1px solid #777;
      15 }
      16 
      17 .float-left{
      18     float: left;
      19 }
      20 
      21 .float-right{
      22     float: right;
      23 }
      24 
      25 #main{
      26     background-color: #94C6DD;
      27      372px;
      28     height: 520px;
      29 }
      30 
      31 #left{
      32 float: left;
      33 
      34 }
      35 
      36 #right{
      37 float: left;
      38 
      39 }
      40 
      41 #candidateZone{
      42  105px;
      43 }
      44 
      45 .description{
      46 border-left: 1px solid #f77;
      47 border-right: 1px solid #f77;
      48  105px;
      49 border-bottom: 5px solid #777;
      50 padding-top: 3px;
      51 }
      52 
      53 .none{
      54     display: none;
      55 }
      56 
      57 button{
      58     margin-top: 2px;
      59     margin-bottom: 3px;
      60 }
      61 </style>
      62 <script>
      63 $(document).ready(function(){
      64 
      65     InitUI();
      66     InitData();
      67     InitVK();
      68     //ShowCandidateType();
      69     //Start();    
      70 
      71 });
      72 
      73 function InitData(){
      74 
      75  curTypeArr = null;
      76  nextTypeArr = null;
      77  pos = {x:0,y:Int(width/2)};
      78  curTypeObjIndex = 0;
      79  curTypeArrPos = [];
      80  flagIsBoundary = false;
      81  curTypeArrPosNextStatus = [];
      82  curTypeArrPosForCubeStatus = [];
      83  AllCubeStatusArr =[];
      84  speed = 1;
      85  score = 0;
      86  clearRowsNum = 0;
      87  nextTypeObjIndex = 0;
      88  stopFlag = false;
      89  firstStart = true;
      90 
      91  $("#level").html("0"+ speed);
      92  $("#score").html(score);
      93  //$("#textStatus").html("No Start");
      94  TextSatutsTimeOut(3,"No Start");
      95     
      96 clearInterval(timeInterval);
      97 InitAllCubeStatusArr();
      98 Types();
      99     //ShowCandidateType();
     100 }
     101 
     102 function InitUI(){
     103     DrawMainUI();
     104     DrawCandidateZoneUI();
     105     DrawOperationZoneUI();
     106 }
     107 
     108 var typeObj = new Object();
     109 var curTypeArr = null;
     110 var nextTypeArr = null;
     111 var width = 10;
     112 var height = 20;
     113 var model_width = width + 2;
     114 var model_height = height + 1;
     115 var pos = {x:0,y:Int(width/2)};
     116 var curTypeObjIndex = 0;
     117 var typeObjAttrList = [["aa","ab"],["ba"],["ca","cb"],["da","db"],["ea","eb","ec","ed"],["fa","fb","fc","fd"],["ga","gb","gc","gd"]];
     118 
     119 var curTypeArrPos = [];
     120 var flagIsBoundary = false;
     121 var curTypeArrPosNextStatus = [];
     122 var curTypeArrPosForCubeStatus = [];
     123 var AllCubeStatusArr =[];
     124 
     125 var speed = 1;
     126 var score = 0;
     127 var clearRowsNum =0;
     128 var nextTypeObjIndex = 0;
     129 var timeInterval = null;
     130 var stopFlag = false;
     131 var PauseFlag = false;
     132 var firstStart = true;
     133 var mainbgcolor = "#94C6DD";
     134 
     135 
     136 function InitAllCubeStatusArr(){
     137     //U type, Arr is (width +2 )*(height+1)
     138     
     139     //reset AllCubeStatusArr
     140     AllCubeStatusArr = [];
     141     for (var j = height  ; j >= 0; j--) {
     142         AllCubeStatusArr[j] = new Array([0]);
     143     for (var i = width + 1 ; i >= 0; i--) {
     144         AllCubeStatusArr[j][i] = 0;
     145         }
     146         
     147     }
     148     
     149     for (var j = height ; j >= 0; j--) {
     150         AllCubeStatusArr[j][0] = 1;
     151         AllCubeStatusArr[j][width +1] = 1;
     152     }
     153     for (var i = width ; i >= 0; i--) {
     154         AllCubeStatusArr[height][i] = 1;
     155     }
     156 
     157     //RefreshDrawUI();
     158 }
     159 
     160 function printAllCubeStatusArr(){
     161     
     162     var content = "";
     163     var row = AllCubeStatusArr.length;
     164     var col = AllCubeStatusArr[0].length;
     165     for (var j =0 ; j < row; j++) {
     166         for (var i = 0 ; i < col; i++) {
     167          content +=(" "+AllCubeStatusArr[j][i]);
     168         }
     169         console.log("row="+j+":"+content+"
    ");
     170         content = "";
     171     }
     172     
     173 }
     174 
     175 function UpdateAllCubeStatusArr(){
     176     //last type done will execute the function
     177     
     178     for (var i = curTypeArrPosForCubeStatus.length - 1; i >= 0; i--) {
     179         var row = Int(curTypeArrPosForCubeStatus[i] / model_width);
     180         var col = Int(curTypeArrPosForCubeStatus[i] % model_width);
     181         //if(row < height){
     182             AllCubeStatusArr[row][col] = 1;
     183             $("#mtd_"+ curTypeArrPosForCubeStatus[i]).attr("flag","1");
     184             console.log("i="+i+" 1 = AllCubeStatusArr["+row+"]["+col+"]");
     185         //}
     186         
     187     }
     188     console.log("UpdateAllCubeStatusArr() Complete");
     189     
     190 }
     191 
     192 function RefreshDrawUI(){
     193 
     194 
     195     for(var i = 0; i < model_height -1; i++){
     196         for(var j = 1; j < model_width -1; j++){
     197         
     198             var curId = $("#mtd_"+ (i*model_width+j));
     199             if(AllCubeStatusArr[i][j] == 1){
     200                 curId.css("background-color","#f00");
     201                 //console.log("showCurTypeInMainBoard->red,curId= "+(i*model_width+j ));
     202             }else{
     203                 curId.css("background-color", mainbgcolor);
     204                 //console.log("showCurTypeInMainBoard->white,curId= "+(i*model_width+j ));
     205             }    
     206         }
     207     }
     208     console.log("RefreshDrawUI() Complete");
     209 
     210 }
     211 
     212 
     213 function CheckRemoveRowInline(){
     214     var count = 0;
     215     var clearRow = 0;
     216     for(var i = 0; i < model_height - 1; i++){
     217         for(var j = 1; j < model_width - 1; j++){
     218             if(AllCubeStatusArr[i][j] ==1){
     219                 count ++;
     220             }        
     221         }
     222         if (count == width) {
     223             clearRow = i;
     224             clearRowsNum ++;
     225             RemoveRowInline(clearRow);
     226             RefreshDrawUI();            
     227         }
     228 
     229         count = 0;
     230 
     231     }
     232     UpdateScore();
     233     
     234 }
     235 
     236 function RemoveRowInline(row){
     237     
     238     for(var i = row ; i > 0; i--){
     239         for(var j = 1; j < model_width - 1; j++){    
     240             
     241             AllCubeStatusArr[i][j] = AllCubeStatusArr[i-1][j];
     242         
     243         }
     244 
     245     }
     246     $("#textStatus").html("<div style='color:red'>remove "+clearRowsNum+" row!");
     247     TextSatutsTimeOut();
     248     console.log("RemoveRowInline row="+row);
     249 }
     250 
     251 
     252 function UpdateScore(){
     253     var lastScore =    score;
     254     if(clearRowsNum == 1){
     255         score += 1;
     256     }else if(clearRowsNum == 2){
     257         score += 3;
     258     }else if(clearRowsNum == 3){
     259         score += 6;
     260     }else if(clearRowsNum == 4){
     261         score += 10;
     262     }else{// when clearRowsNum = 0, it will not happen
     263         //score += 0;
     264     }
     265 
     266     //reset
     267     clearRowsNum = 0;
     268 
     269     if(score >= 20 && lastScore < 20){
     270         UpdateLevel();    
     271     }else if(score >= 40 && lastScore < 40){
     272         UpdateLevel();    
     273     }else if(score >= 60 && lastScore < 60){
     274         UpdateLevel();
     275     }else if(score >= 80 && lastScore < 80){
     276         UpdateLevel();    
     277     }else if(score >= 100 && lastScore < 100){
     278         UpdateLevel();
     279     }else if(score >= 120 && lastScore < 120){
     280         UpdateLevel();
     281     }else if(score >= 140 && lastScore < 140){
     282         UpdateLevel();
     283     }else if(score >= 147){
     284         score = 147;
     285         $("#textStatus").html("<div style='color:green'><b>Win</b>");
     286         //TextSatutsTimeOut(10);
     287         firstStart = true;
     288         
     289         var t =setInterval(function(){
     290             
     291             for(var i = height -1 ; i > 0; i--){
     292             for(var j = 1; j < model_width - 1; j++){                    
     293                 AllCubeStatusArr[i][j] = AllCubeStatusArr[i-1][j];        
     294                 }
     295             }
     296 
     297             RefreshDrawUI();    
     298             },500);
     299 
     300         setTimeout(function(){
     301             clearInterval(t);
     302             $("#reset").trigger("click");
     303             },500*height);    
     304     }
     305 
     306     $("#score").html(score);
     307 }
     308 
     309 function UpdateLevel(){
     310     // speed value from  1 to 6, Max is 6
     311     speed = Int(score / 20);
     312     $("#level").html("0"+ speed);
     313     if ( score >= 20 ) {
     314         $("#textStatus").html("<div style='color:green'>Congratulation! You have arrived "+speed+" Level");
     315         TextSatutsTimeOut(5);
     316     }
     317 
     318 }
     319 
     320 function CheckGameOver(){
     321     for(var i=0; i<curTypeArrPos.length;i++)
     322     
     323         if(CheckNextStatusIsBoundary()){
     324             if (Int(curTypeArrPos[i] / model_width) == 0) {
     325 
     326             console.log("Game Over! Your Score is="+$("#score").text());
     327             $("#textStatus").html("<div style='color:red'><b>Game over</b>");
     328             $('#score').html('<b style="color:green">'+$('#score').text()+'</b>');
     329             
     330             clearInterval(timeInterval);
     331 
     332             setTimeout(function(){
     333                 $('#reset').trigger('click');
     334             },3000);
     335 
     336             break;
     337 
     338         }
     339     }
     340 
     341 }
     342 
     343 function TextSatutsTimeOut(seconds,msg){
     344     if (typeof seconds == 'undefined') {
     345         seconds = 3;
     346     }
     347     if (typeof msg == 'undefined') {
     348         msg="playing";
     349     }
     350     setTimeout(function(){
     351         $("#textStatus").html(msg);            
     352         },seconds*1000);
     353 
     354 }
     355 
     356 function Int(number){
     357 
     358     return Math.floor(number);
     359 
     360 }
     361 
     362 function CheckNextStatusIsBoundary(reCheck){
     363     
     364     for (var i = curTypeArrPos.length - 1; i >= 0; i--) {
     365 
     366             if(curTypeArrPosNextStatus[i] >= model_width * (model_height-1)){
     367                     return true;
     368                 }
     369 
     370             if (reCheck == true ) {
     371                 UpdatePosNextStatus(KEY_DOWN);
     372                 if(CubeInBlock(curTypeArrPosNextStatus[i])){
     373                     return true;
     374                 }
     375                 console.log("reCheck i="+i);
     376             }
     377             else if(CubeInBlock(curTypeArrPosNextStatus[i])){
     378                 console.log("CheckNextStatusIsBoundary_i_val_ret="+i+" "+curTypeArrPosNextStatus[i]+" true");
     379                 return true;
     380             }
     381         }
     382         console.log("CheckNextStatusIsBoundary_i_val_ret="+i+" "+false);
     383     return false;
     384 }
     385 
     386 /*function CheckCurTypeStatusIsBottomBoundary(){
     387 
     388 for (var i = curTypeArrPosNextStatus.length - 1; i >= 0; i--) {
     389         //bottom check boundary when first start 
     390         if(curTypeArrPosNextStatus[i] >= model_width * (model_height-1)){
     391             console.log("CheckCurTypeStatusIsBottomBoundary0="+curTypeArrPosNextStatus[i]);
     392             return true;
     393         }
     394 
     395         //If NextStatus is Boundary, then NextNextStatus will be in CubeInBlock
     396         if(CubeInBlock(curTypeArrPosNextStatus[i] + model_width)){
     397             console.log("CheckCurTypeStatusIsBottomBoundary1="+curTypeArrPosNextStatus[i]);
     398             return true;
     399         }
     400     }
     401     return false;
     402 
     403 }
     404 */
     405 
     406 function CubeInBlock(number){
     407 
     408     var row = Int(number / model_width);
     409     var col = Int(number % model_width);
     410     console.log("CubeInBlock_num_row_col="+ number+" "+row+" "+col);
     411     if (AllCubeStatusArr[row][col] == 1){
     412         console.log("CubeInBlock_num is in block="+ number);
     413         return true;
     414     }
     415     
     416     return false;
     417 }
     418 
     419 
     420 
     421 function Types(){
     422 //five type
     423 typeObj.aa = [[1,1,1,1],[0,0,0,0],[0,0,0,0],[0,0,0,0]];//----
     424 typeObj.ab = [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]];//clockwise rotate 90 degree
     425 
     426 typeObj.ba = [[1,1,0,0],[1,1,0,0],[0,0,0,0],[0,0,0,0]];//
     427 
     428 typeObj.ca = [[1,1,0,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]];//z
     429 typeObj.cb = [[0,1,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]];//clockwise rotate 90 degree
     430 
     431 typeObj.da = [[0,1,1,0],[1,1,0,0],[0,0,0,0],[0,0,0,0]];//mirror z
     432 typeObj.db = [[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,0,0,0]];//clockwise rotate 90 degree
     433 
     434 typeObj.ea = [[0,1,0,0],[0,1,0,0],[1,1,0,0],[0,0,0,0]];//mirror L
     435 typeObj.eb = [[1,0,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]];//clockwise rotate 90 degree
     436 typeObj.ec = [[1,1,0,0],[1,0,0,0],[1,0,0,0],[0,0,0,0]];//clockwise rotate 180 degree
     437 typeObj.ed = [[1,1,1,0],[0,0,1,0],[0,0,0,0],[0,0,0,0]];//anticlockwise rotate 90 degree
     438 
     439 typeObj.fa = [[1,0,0,0],[1,0,0,0],[1,1,0,0],[0,0,0,0]];//L
     440 typeObj.fb = [[1,1,1,0],[1,0,0,0],[0,0,0,0],[0,0,0,0]];//clockwise rotate 90 degree
     441 typeObj.fc = [[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]];//
     442 typeObj.fd = [[0,0,1,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]];//
     443 
     444 typeObj.ga = [[0,1,0,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]];//I---
     445 typeObj.gb = [[1,0,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]];
     446 typeObj.gc = [[1,1,1,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]];
     447 typeObj.gd = [[0,1,0,0],[1,1,0,0],[0,1,0,0],[0,0,0,0]];
     448 
     449 }
     450 
     451 
     452 $(window).keypress(function(event){
     453     
     454     var currKey = event.keyCode || event.which || event.charCode;
     455     var keyName = String.fromCharCode(currKey); 
     456     console.log("keyCode: " + currKey + " charCode: " + keyName); 
     457   
     458   switch(currKey) {
     459     case 119:
     460     case 87:
     461         KeyHanderUp();
     462         break;
     463     case 115:
     464     case 83:
     465         KeyHanderDown();
     466         break;
     467     case 97:
     468     case 65:
     469         KeyHanderLeft();
     470         break;
     471     case 100:
     472     case 68:
     473         KeyHanderRight();
     474         break;
     475     }
     476     console.log("pos(x,y)=["+pos.x+","+pos.y+"]");
     477 });
     478 
     479 function KeyHanderUp(){
     480 
     481 if (!flagIsBoundary && !PauseFlag && !firstStart) {
     482     eraseCurTypeUI();
     483     //default rotate dir is right
     484     var curTypeArrRotate = null;
     485     var nextAttr = null;
     486     console.log("curIndex ="+(curTypeObjIndex));
     487 
     488     if(curTypeObjIndex == 0){
     489         nextAttr = typeObjAttrList[0][1];
     490         curTypeObjIndex = 1;
     491     }else if(curTypeObjIndex == 1 ){
     492         nextAttr = typeObjAttrList[0][0];
     493         curTypeObjIndex = 0;
     494     }else if(curTypeObjIndex == 2){
     495         nextAttr = typeObjAttrList[1][0];
     496         curTypeObjIndex = 2;
     497     }else if(curTypeObjIndex == 3){
     498         nextAttr = typeObjAttrList[2][1];
     499         curTypeObjIndex = 4;
     500     }else if(curTypeObjIndex == 4 ){
     501         nextAttr = typeObjAttrList[2][0];
     502         curTypeObjIndex = 3;
     503     }else if(curTypeObjIndex == 5){
     504         nextAttr = typeObjAttrList[3][1];
     505         curTypeObjIndex = 6;
     506     }else if(curTypeObjIndex == 6 ){
     507         nextAttr = typeObjAttrList[3][0];
     508         curTypeObjIndex = 5;
     509     }else if(curTypeObjIndex >= 7){
     510         //first four rows number is 2+1+2+2 = 7, add 9 is 4 * 4 = 16
     511         var index = curTypeObjIndex + 9;
     512         var row =Math.floor(index / 4);
     513         var col =Math.floor(index % 4);
     514         //var curAttr = typeObjAttrList[row][col];
     515         
     516         if (col < 3) {
     517             nextAttr = typeObjAttrList[row][col+1];
     518             curTypeObjIndex ++;
     519         }else{
     520             col = 0;
     521             nextAttr = typeObjAttrList[row][col];
     522             
     523             if ((curTypeObjIndex+9) % 4 == 3) {
     524                 curTypeObjIndex -= 3;
     525             };
     526         }
     527                 
     528     }
     529 
     530     curTypeArrRotate = typeObj[nextAttr];
     531 
     532     curTypeArrPosNextStatus = [];
     533     for(var i = 0; i < 4; i++){
     534     for(var j = 0; j < 4-i; j++){
     535         if (curTypeArrRotate[i][j] == 1) {
     536             var id = (i+pos.x)*model_width+j+(pos.y)
     537             curTypeArrPosNextStatus.push(id);
     538             }
     539         }
     540             
     541     }
     542 
     543     if(! CheckNextStatusIsBoundary()){
     544         curTypeArr = typeObj[nextAttr];
     545     }else{
     546         curTypeObjIndex --;
     547         //Fix Type aa -> ab
     548         if (curTypeObjIndex < 0) {
     549             curTypeObjIndex = 1;
     550         };
     551     }
     552     
     553     showCurTypeInMainBoard();
     554     }
     555 }
     556 
     557 
     558 function KeyHanderDown(){
     559     
     560     if (!flagIsBoundary && !PauseFlag && !firstStart) {
     561         eraseCurTypeUI();
     562         pos.x ++;
     563         //Remember last status before conflict check 
     564 
     565         UpdatePosNextStatus(KEY_DOWN);
     566         if(CheckNextStatusIsBoundary()){
     567             pos.x --;
     568 
     569             flagIsBoundary =true;
     570         
     571         setTimeout(function(){
     572             
     573             //Remember last status before conflict check 
     574             for (var i = curTypeArrPosNextStatus.length - 1; i >= 0; i--) {
     575                 curTypeArrPosForCubeStatus[i] = curTypeArrPosNextStatus[i];
     576             }
     577 
     578             if(!CheckNextStatusIsBoundary(true)){
     579                 flagIsBoundary = false;
     580             }else{
     581 
     582             PauseFlag = true;
     583             UpdateAllCubeStatusArr();
     584             RefreshDrawUI();
     585             CheckRemoveRowInline();
     586             if(!CheckGameOver()){
     587                 PauseFlag = false;
     588                 Next();
     589             }
     590         }
     591             
     592         },300);
     593     }
     594     
     595     showCurTypeInMainBoard();
     596     }
     597 
     598 
     599 }
     600 
     601 //var KEY_UP = 0;
     602 var KEY_DOWN = 1;
     603 var KEY_LEFT = 2;
     604 var KEY_RIGHT = 3;
     605 
     606 function UpdatePosNextStatus(keyStatus){
     607     var offset =0;
     608     if (keyStatus == KEY_LEFT){
     609         offset = -1;
     610     }else if (keyStatus == KEY_RIGHT) {
     611         offset = 1;
     612     }else if (keyStatus == KEY_DOWN){ //KEY_DOWN 
     613         offset = model_width;
     614     }else{//KEY_UP
     615         offset = -model_width;
     616     }
     617 
     618     for (var i = curTypeArrPosNextStatus.length - 1; i >= 0; i--) {
     619         curTypeArrPosNextStatus[i] += offset;
     620     }
     621 }
     622 
     623 function KeyHanderLeft(){
     624     
     625     if(!PauseFlag && !firstStart){
     626     eraseCurTypeUI();
     627     pos.y --;
     628         
     629     UpdatePosNextStatus(KEY_LEFT);
     630 
     631     if (CheckNextStatusIsBoundary()) {
     632         
     633         //curTypeArrPosForCubeStatus = curTypeArrPosNextStatus;
     634         pos.y ++;
     635         
     636         }
     637     showCurTypeInMainBoard();
     638     }
     639 
     640 }
     641 
     642 function KeyHanderRight(){
     643     
     644     if(!PauseFlag && !firstStart){
     645     eraseCurTypeUI();
     646     pos.y ++;
     647         
     648     UpdatePosNextStatus(KEY_RIGHT);
     649     if (CheckNextStatusIsBoundary()) {
     650         //curTypeArrPosForCubeStatus = curTypeArrPosNextStatus;
     651         pos.y --;
     652     }
     653 
     654     showCurTypeInMainBoard();
     655     }
     656 }
     657 
     658 
     659 function showCurTypeInMainBoard(){
     660     // reset curTypeArrPos data
     661     curTypeArrPos = [];
     662     curTypeArrPosNextStatus = [];
     663     for(var i = 0; i < 4; i++){
     664     for(var j = 0; j < 4-i; j++){
     665         if (curTypeArr[i][j] == 1) {
     666             var id = (i+pos.x)*model_width+j+(pos.y);
     667             $("#mtd_"+ id).css("background-color","#f00");
     668             //console.log("showCurTypeInMainBoard->red,id="+curTypeArr[i][j] +" "+id );
     669             curTypeArrPos.push(id);
     670             curTypeArrPosNextStatus.push(id);
     671             }
     672         }
     673             
     674     }
     675     
     676 }
     677 
     678 function GetRandType(){
     679     var type = null;
     680     var i =0;
     681     var randNum =Math.floor(Math.random()*19);
     682     for (x in typeObj) {
     683         type = typeObj[x];
     684 
     685         if (randNum == i) {
     686             break;
     687         };
     688         i++;
     689     };
     690     nextTypeObjIndex = randNum;
     691     console.log("GetRandType_curTypeObjIndex=" + curTypeObjIndex);
     692     
     693     return type;
     694 }
     695 
     696 
     697 function ShowCandidateType(){
     698 
     699     nextTypeArr = GetRandType();
     700     //nextTypeObjIndex =  curTypeObjIndex;
     701     //reset color to white
     702     for(var i = 0; i < 4; i++){
     703         for(var j = 0; j < 4-i; j++){    
     704         $("#ctd_"+(i*4+j)).css("background-color", mainbgcolor);            
     705         }
     706             
     707     }
     708 
     709     for(var i = 0; i < 4; i++){
     710         for(var j = 0; j < 4-i; j++){
     711         if (nextTypeArr[i][j] == 1) {
     712                 $("#ctd_"+(i*4+j)).css("background-color","#f00");
     713             }
     714         }
     715             
     716     }
     717 }
     718 
     719 function DrawMainUI(){
     720 
     721     //reset div
     722     $("#left").html("");
     723     var table = $("<table>").appendTo($("#left"));
     724     for(var i = 0; i < model_height - 1; i++){
     725         var row = $("<tr>").appendTo(table);
     726     for(var j = 1; j < model_width - 1 ; j++){
     727      //row.append("<td>null</td>");
     728         $("<td id=mtd_"+(i*model_width+j)+" style='20px;height:20px'></td>").appendTo(row); 
     729     
     730         }
     731             
     732     }
     733 }
     734 
     735 function DrawCandidateZoneUI(){
     736     //reset div
     737     $("#candidateZone").html("");
     738     var table = $("<table>").appendTo($("#candidateZone"));
     739     for(var i = 0; i < 4; i++){
     740     var row = $("<tr>").appendTo(table);
     741     for(var j = 0; j < 4; j++){
     742      //row.append("<td>null</td>");
     743     $("<td id=ctd_"+(i*4+j)+" style='20px;height:20px'></td>").appendTo(row); 
     744     
     745         }
     746             
     747     }
     748 }
     749 
     750 function DrawOperationZoneUI(){
     751 
     752 
     753     var content ="";
     754 
     755     var div_custom = $("<div>").appendTo($("#custom"));
     756         content = "<div><b>Custom</b></div><div>width :<input id='width' style='40px' placeholder='5-20'/></div>"
     757                 + "<div>height:<input id='height' style='40px' placeholder='5-20'/></div>"
     758                 + "<button id='customOk'>OK</button>"
     759                 + "&nbsp;"
     760                 + "<button id='customClear'>Clear</button>";
     761     div_custom.html(content);
     762 
     763     var div_debug = $("<div>").appendTo($("#debugZone"));
     764         content = "<button id='refresh'>RefreshUI</button>"    
     765                 + "<button id='printAllCubeStatusArr'>printStatusArr</button>"
     766                 + "<div>SetLevel :<input id='setLevel' style='20px' placeholder='1-7'/></div>"
     767                 + "<div>SetScore :<input id='setScore' style='20px' placeholder='147'/></div>"
     768                 + "<button id='debugOk'>OK</button>"
     769                 + "&nbsp;"
     770                 + "<button id='debugClear'>Clear</button>"
     771                 + "<button id='debugHide' style='100%'>Hide</button>";
     772     div_debug.html(content);
     773 
     774     var div_manual = $("<div>").appendTo($("#manual"));
     775         content = "<div>Manual:Press WSAD is for UP DOWN LEFT RIGHT or Using below virtual nav key</div>";
     776     div_manual.html(content);
     777 
     778     var div_score = $("<div style='background-color:#77ff77; 372px; font-size:larger'>").appendTo($("#scoreZone"));
     779          content = "<b>Level:</b><span id='level'>01</span>"
     780                 + "<b style='padding-left:95px'>Score:</b><span id='score'>0</span>";
     781     div_score.html(content);
     782 
     783     var div_play = $("<div>").appendTo($("#playZone"));
     784          content = "<button id='play' >Play</button>"
     785                 + "<button id='reset' class='float-right'>Reset</button>";
     786     div_play.html(content);
     787 
     788     var div_text = $("<div>").appendTo($("#textStatusZone"));
     789          content = "<div>Status: </div>"
     790                  + "<div id='textStatus'>No Start</div>";
     791     div_text.html(content);
     792 
     793     var div_nav = $("<div>").appendTo($("#virtualNav"));
     794          content = "<button id='v_up' style='100%'>Up</button>"
     795                 + "<button id='v_left' class='float-left'>Left</button>"
     796                 + "<button id='v_right' class='float-right'>Right</button>"
     797                 + "<button id='v_down' style='100%'>Down</button>";
     798     div_nav.html(content);
     799 }
     800 
     801 function InitVK(){
     802 
     803     //custom
     804     $("#customOk").click(function(){
     805         var cwidth = parseInt($("#width").val());
     806         var cheight =parseInt($("#height").val());
     807         if (cwidth >= 5 && cheight >=5 && cwidth <= 20 &&cheight <=20) {
     808             width = cwidth;
     809             height =cheight;
     810             model_width = width + 2;
     811             model_height = height + 1;
     812             $("#textStatus").html("custom setting done");
     813             $("#reset").trigger('click');
     814             $("#main").css('width',width/10*260+112+'px');
     815             $("#scoreZone > div").css('width',width/10*260+112+'px');
     816 
     817 
     818         }else{
     819             $("#textStatus").html("width or height size both is among <b>5-20</b>");
     820             
     821         }
     822         TextSatutsTimeOut(3,"No Start");
     823 
     824         //open debugZone
     825         if (cwidth == "520" || cheight =="520") {
     826             $("#debugZone").removeClass("none");
     827             $("#debugZone").css("border","1px solid #0f0");
     828         }
     829     });
     830 
     831     $("#customClear").click(function(){
     832             
     833         if($("#width").val() == "" && $("#height").val() == ""){
     834             $("#textStatus").html("Don't Press Clear button when no value");
     835              
     836              setTimeout(function(){
     837                 $("#textStatus").html("No Start");            
     838              },2000);
     839         
     840         }else{
     841              $("#width").val("");
     842              $("#height").val("");
     843              $("#textStatus").html("Clear Custom width and height");
     844             
     845              setTimeout(function(){
     846                 $("#textStatus").html("No Start");            
     847              },2000);
     848          }
     849          
     850     });
     851     
     852     //debugZone
     853     $("#printAllCubeStatusArr").click(function(){
     854         printAllCubeStatusArr();
     855     });
     856 
     857     $("#refresh").click(function(){
     858         RefreshDrawUI();
     859     });
     860     
     861     $("#debugOk").click(function(){
     862         var dlevel = parseInt($("#setLevel").val());
     863         var dScore =parseInt($("#setScore").val());
     864         if (dlevel <= 7 && dlevel >=1) {
     865             speed = dlevel -1;    
     866             $("#level").html("0"+dlevel);
     867             
     868         }else{
     869             $("#textStatus").html("level is among <b>1-7</b>");    
     870         }
     871 
     872         if (dScore <= 147 && dScore >= 0) {
     873             score = dScore;
     874             $("#score").html(dScore);
     875             //$("#textStatus").html("setScore done");
     876         }else{
     877             $("#textStatus").html("level is among <b>1-7</b> and Score is among <b>0-147</b>");    
     878         }    
     879 
     880         setTimeout(function(){
     881             $("#textStatus").html("No Start");            
     882         },5000);
     883 
     884 
     885     });
     886 
     887     $("#debugClear").click(function(){
     888             
     889         if($("#width").val() == "" && $("#height").val() == ""){
     890             $("#textStatus").html("Don't Press Clear button when no value");
     891              
     892              setTimeout(function(){
     893                 $("#textStatus").html("No Start");            
     894              },2000);
     895         
     896         }else{
     897              $("#setLevel").val("");
     898              $("#setScore").val("");
     899              $("#textStatus").html("Clear Level and Score");
     900             
     901              setTimeout(function(){
     902                 $("#textStatus").html("No Start");            
     903              },2000);
     904          }
     905          
     906     });
     907 
     908     $("#debugHide").click(function(){
     909 
     910         $("#debugZone").addClass("none");
     911             $("#textStatus").html("Debug Zone has hided");         
     912              setTimeout(function(){
     913                 $("#textStatus").html("No Start");            
     914              },2000);     
     915     });
     916     
     917     //playZone
     918     $("#play").click(function(){
     919     
     920         if($("#play").text() == "Pause"){
     921             clearInterval(timeInterval);
     922             $("#play").html("<b>Play<b>");
     923             PauseFlag = true;
     924             $("#textStatus").html("game is paused");
     925         }else{//$("#play").text() == "Play"
     926             Play();
     927             if(firstStart){
     928                 //init nextTypeArr show CandidateType
     929                 ShowCandidateType();
     930                 Start();
     931                 firstStart = false;
     932             }
     933 
     934             $("#play").text("Pause");
     935             PauseFlag = false;
     936             $("#textStatus").html("playing");
     937         }        
     938 
     939     });
     940 
     941     $("#reset").click(function(){
     942         DrawMainUI();
     943         DrawCandidateZoneUI();
     944         InitData();
     945         //firstStart = true;
     946         clearInterval(timeInterval);
     947         $("#play").text("Play");
     948 
     949         
     950     });
     951 
     952     //nav
     953     $("#v_up").click(function(){
     954         KeyHanderUp();
     955     });
     956 
     957     $("#v_down").click(function(){
     958         KeyHanderDown();
     959     });
     960 
     961     $("#v_left").click(function(){
     962         KeyHanderLeft();
     963     });
     964 
     965     $("#v_right").click(function(){
     966         KeyHanderRight();
     967     });
     968 
     969 }
     970 
     971 
     972 function Start(){
     973     //ShowCandidateType();
     974     curTypeArr = nextTypeArr;
     975     var lastTypeObjIndex = nextTypeObjIndex;
     976     ShowCandidateType();
     977     curTypeObjIndex = lastTypeObjIndex;
     978     showCurTypeInMainBoard();
     979 }
     980 
     981 
     982 
     983 function Next(){
     984     
     985     if(flagIsBoundary){
     986         flagIsBoundary = false;
     987         pos = {x:0,y:Int(width/2)};
     988         Start();
     989     }
     990     console.log("Next() Complete");
     991 
     992 }
     993 function Play(){
     994     timeInterval = setInterval(function(){
     995         KeyHanderDown();
     996     },(8-speed)*70);
     997 }
     998 
     999 function eraseCurTypeUI(){
    1000     for(var i = 0; i < 4; i++){
    1001         $("#mtd_"+curTypeArrPos[i]).css("background-color", mainbgcolor);
    1002     }
    1003 
    1004 }
    1005 
    1006 </script>
    1007 
    1008 
    1009 </head>
    1010 <body>
    1011 <h3>Welcome to my game exercise - Tetris</h3>
    1012 <div id ="manual">
    1013 </div>
    1014         <div id ="scoreZone">
    1015         </div>
    1016 <div id="main">
    1017     <div id="left">
    1018     </div>
    1019     <div id="right">
    1020         <div id="candidateZone">
    1021         </div>
    1022         <div id ="custom" class="description">
    1023         </div>
    1024         <div id ="debugZone" class="description none">
    1025         </div>
    1026 
    1027         <div id ="playZone" class="description">
    1028         </div>
    1029         <div id ="virtualNav" class="description">
    1030         </div>
    1031         <div id ="textStatusZone" class="description">
    1032         </div>
    1033     </div>
    1034 </body>
    1035 </html>
    View Code

    6.总结

    我敲代码,可以认认真真地敲到凌晨1点,这个是我之前没预期到的。
    开发时,要用版本工具来控制,我使用TortoiseSVN。
    最后,如果你有疑问,请在评论区提问,谢谢!
  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/fanbi/p/6573580.html
Copyright © 2011-2022 走看看