• 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。
    最后,如果你有疑问,请在评论区提问,谢谢!
  • 相关阅读:
    批量数据导入数据库方法
    Remoting简单实践
    js面向对象继承
    Linq实现t-Sql的各种连接
    数据库树状结构的关系表的删除方案
    记录一次SQL查询语句
    mvc请求过程总结
    T-sql表表达式
    各个浏览器的兼容问题及样式兼容处理(不定期补充)
    vue.js 键盘enter事件的使用
  • 原文地址:https://www.cnblogs.com/fanbi/p/6573580.html
Copyright © 2020-2023  润新知