俄罗斯方块html小游戏


第一次学html、css、javascript,也第一次用他们来写东西——俄罗斯方块。总结了一下


一、需求
基本流程:
1、画表格 
2、创建一个与表格里每个小格对应的标记数组
3、随机生成七种方块
4、键盘触发
5、使方块能按照键盘的按键改变方向、加速等
6、碰撞判断及消行
7、更新分数
8、预告功能
9、其他功能
二、详细设计
1、画表格。
用html定义了两个表格。一个用来显示运动方块,一个用来预告即将生成的方块
 
2、创建了一个二维数组,初始值为0,填满后复制1。


3、随机生成七种方块


利用Math.floor(Math.random() * 7)生成0~6的随机整数,每个整数对应一种方块。
每个方块由四个小方格组成,每个小方格均有XY坐标。


4、键盘触发


想要接收按键事件, 就要用到document的onkeydown,将写好的方法赋值给onkeydo\wn,


5、改变方向,加速下降等


左右移:比较简单。方格(每个均要判断)的X值不变,改变Y值。看能否左右移。如果能左右移,则改变Y值。同时更新标记数组,重绘表格
下移:分为匀速下移和加速下移,均采用setInterval()定时函数,加速下降则才调用该函数一次。
改变方向:比较复杂。在网上参考了一些转变的方法。算出中位数,然后根据中位数改变各方格的坐标。在转变前还必须判断转变后的坐标是否符合要求


6、碰撞分析及消行
按照碰撞后能否消行分为两种。
不能消行则停止下降,更新标记数组,然后重绘表格,生成新的方块
能消行则更新数组(将上面的数组下移),重绘画布,然后继续生成新的方块


7、更新分数
根据消除的行数来更新分数。同时将其显示出来,原理差不多和显示动态的方块画布一样。


8、其他细节
(1)预示方块,必须在每次生成当前方块前
(2)下落操作比较难。除了需判断碰撞外,考虑消行,更新分数,及继续定时生成新的方框
(3)旋转操作,需先算出中心坐标,然后在根据数学公式转变其坐标,改变前需对其判断是否合法、是否出界
(4)消行操作,纠结的最久的。

一开始,更新数组,清除画布,重绘画布很乱。

(5)浏览器兼容问题(原先IE,chrome都行,就firefox不行)后来用 var event = window.event || e搞定了




三、总结


1、没有在一开始好好安排下时间,需要哪些学哪些知识。致使后来有些乱,进度赶不上


2、语法不熟悉,犯了很多低级错误


3、函数多,有些乱。在开始前最好能把所有的函数列出来,比较清晰


4、写的过程没注意去调试各个函数。也没学好怎样调试。导致后来花很多时间在调试上


附:html文件

<html>
  <head>
<title>俄罗斯方块</title>
 <style>
#board tr td{
width: 18px;
height:18px;

}
#board1 tr td{
width: 10px;
height:10px;

}

.STYLE1 {
width: 40px;
height: 30px;
font-size: xx-large;
color: #FF0000;
}
        .STYLE2 {
color: #000000;
font-size: x-large;
}
.STYLE7 {color: #FF0000}
 </style>

</head>
<script type="text/javascript" language="javascript" src="eluosi.js"></script>

<body>

<p align="center" > <input name="button" type="button" onClick="begin(this);" value="begin"/> </p> 

<table width="222" align="center" border="1">
      <tr >
        <td width="214" align="center" bgcolor="#00FF33"  class="STYLE1"><span class="STYLE2"></span>score:<span id="score" >0</span> </td>
      </tr>
    </table>

<br>

<table  id="board1"  border="0" align="center" cellpadding="0" cellspacing="0">
 <tr> 
    <td colspan="4" bgcolor="#00FF00"><span class="STYLE7">next:</span></td>
    </tr>
<tr> 
    <td></td>
    <td></td>
    <td></td>
<td></td>
    </tr>
  <tr>
    <td></td>
<td></td>
    <td></td>
    <td></td>
    </tr>
  <tr>
    <td></td>
    <td></td>
<td></td>
    <td></td>
    </tr>
</table>


<br>
    <table id="board" align="center" cellpadding="0" cellspacing="0" border="1" style="border-collapse:collapse;">
       <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  

                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  

            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
            <tr>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
                <td></td>  
            </tr>  
      </table> 
      
</body>  
</html>



js文件:



var m=0;
var n=0;
        var tbl;  
var tbl1;
        var status = 0;  
        var time; 
var activeBlock;  //活动的方块
var activeBlock1;  //预览下个方块
//得分
        var score = 0;

        var board = new Array(18); 
        for(var i=0;i<18;i++){ 
            board[i] = new Array(10);  
        } 
        for(var i=0;i<18;i++){  
            for(var j=0; j<10; j++){  
                board[i][j] = 0;  
            }  
        }  

//预览方块
activeBlock1=new Array(4);
//预览方块标记数组
var board1 = new Array(4); 
        for(var i=0;i<4;i++){ 
            board1[i] = new Array(4);  
        } 
        for(var i=0;i<4;i++){  
            for(var j=0; j<4; j++){  
                board1[i][j] = 0;  
            }  
        }  


             //生成预览方块
         function next(){
m=Math.floor(Math.random() * 7);
clearBoard1();
switch(m){
case 0:{
    activeBlock1[0]={x:1,y:1};
    activeBlock1[1]={x:1,y:2};
    activeBlock1[2]={x:2,y:1};
    activeBlock1[3]={x:2,y:2};
break;
}
  case 1:{
    activeBlock1[0]={x:2,y:0};
    activeBlock1[1]={x:2,y:1};
    activeBlock1[2]={x:2,y:2};
    activeBlock1[3]={x:2,y:3};
break;
}
  case 2:{
    activeBlock1[0]={x:1,y:2};
    activeBlock1[1]={x:2,y:1};
    activeBlock1[2]={x:2,y:2};
    activeBlock1[3]={x:3,y:1};
break;
}
  case 3:{
    activeBlock1[0]={x:1,y:1};
    activeBlock1[1]={x:2,y:1};
    activeBlock1[2]={x:2,y:2};
    activeBlock1[3]={x:3,y:2};
break;
}
  case 4:{
    activeBlock1[0]={x:1,y:1};
    activeBlock1[1]={x:2,y:1};
    activeBlock1[2]={x:2,y:2};
    activeBlock1[3]={x:2,y:3};
break;
}
  case 5:{
    activeBlock1[0]={x:1,y:1};
    activeBlock1[1]={x:2,y:1};
    activeBlock1[2]={x:3,y:1};
    activeBlock1[3]={x:3,y:2};
break;
}
  case 6:{
    activeBlock1[0]={x:1,y:1};
    activeBlock1[1]={x:2,y:0};
    activeBlock1[2]={x:2,y:1};
    activeBlock1[3]={x:2,y:2};
break;
}
}      
updateBoard1();
drawBoard1();  
}
 
  //更新预览的标记数组
function updateBoard1(){  

            for(var i=0; i<4; i++) 
               { board1[activeBlock1[i].x][activeBlock1[i].y]=1;}
        } 

//擦除预览的面板
   function clearBoard1(){ 
            for(var i=1; i<4; i++){ 
                for(var j=0; j<4; j++){ 
board1[i][j]=0;
                    tbl1.rows[i].cells[j].style.backgroundColor = "white"; 
                } 
            } 
        } 

        //重绘面板 
        function drawBoard1(){ 
            for(var i=1;i<4;i++){ 
                for(var j=0; j<4; j++){  
                  if(board1[i][j]==1){ 
                    tbl1.rows[i].cells[j].style.backgroundColor = "red"; 
                  } 
                }  
            }  
        } 
 
       //生产七种方块 
          function createBlock(){     
          activeBlock=null;
activeBlock=new Array(4);
switch(m){
case 0:{
    activeBlock[0]={x:0,y:3};
    activeBlock[1]={x:0,y:4};
    activeBlock[2]={x:1,y:3};
    activeBlock[3]={x:1,y:4};
break;
}
  case 1:{
    activeBlock[0]={x:0,y:3};
    activeBlock[1]={x:0,y:4};
    activeBlock[2]={x:0,y:5};
    activeBlock[3]={x:0,y:6};
break;
}
  case 2:{
    activeBlock[0]={x:0,y:4};
    activeBlock[1]={x:1,y:3};
    activeBlock[2]={x:1,y:4};
    activeBlock[3]={x:2,y:3};
break;
}
  case 3:{
    activeBlock[0]={x:0,y:3};
    activeBlock[1]={x:1,y:3};
    activeBlock[2]={x:1,y:4};
    activeBlock[3]={x:2,y:4};
break;
}
  case 4:{
    activeBlock[0]={x:0,y:3};
    activeBlock[1]={x:1,y:3};
    activeBlock[2]={x:1,y:4};
    activeBlock[3]={x:1,y:5};
break;
}
  case 5:{
    activeBlock[0]={x:0,y:3};
    activeBlock[1]={x:1,y:3};
    activeBlock[2]={x:2,y:3};
    activeBlock[3]={x:2,y:4};
break;
}
  case 6:{
    activeBlock[0]={x:0,y:4};
    activeBlock[1]={x:1,y:3};
    activeBlock[2]={x:1,y:4};
    activeBlock[3]={x:1,y:5};
break;
}
}
//提前生成预览方块
next();

            //检查生成的方块是否可以放在初始的位置. 
            for(var i=0; i<4; i++){ 
                if(!canFill(activeBlock[i].x, activeBlock[i].y)){ 
                    return false; 
                } 
            } 
            return true; 
        } 

        //向下移动 
        function moveDown(){ 
            //检查能否下移
          if(checkDown()){  
            //没有触底, 则擦除当前图形,  
              clear();  
              //更新当前图形坐标 
              for(var i=0; i<4; i++){ 
                  activeBlock[i].x = activeBlock[i].x + 1;  
              } 
              //重画当前图形 
              draw();  
          } 
          //触底,  
          else{ 
            //停止下降
            clearInterval(time); 
            //更新标记数组. 
            updateBoard(); 
            //消行 
            var lines = deleteLine(); 
            //有消行, 
            if(lines!=0){ 
                //更新分数 
                score = score + lines*10; 
//alert(score);
                updateScore();
                //擦除整个面板 
                clearBoard(); 
                //重绘面板 
                drawBoard(); 
            } 

            //产生一个新图形,判断是否可放在最初的位置. 
            if(!createBlock()){ 
                alert("GAME OVER!"); 
                status = 2; 
                return; 
            } 
            draw(); 

            //定时器, 每隔一秒执行一次moveDown 
            time = setInterval(moveDown,1000) 
          }  
        }  

 //检查底边界 
        function checkDown(){  
            for(var i=0; i<activeBlock.length; i++){  
                if(activeBlock[i].x==17){  
                    return false;  
                }  
                if(!canFill(activeBlock[i].x+1, activeBlock[i].y)){  
                    return false;  
                }  
            }  
            return true;  
        }  

        //左移 
        function moveLeft(){ 
            if(checkLeft()){  
                clear();  
                for(var i=0; i<4; i++){  
                    activeBlock[i].y = activeBlock[i].y - 1;  
                }  
                draw();  
            }  
        }  
        
//检查左边界 
        function checkLeft(){  
            for(var i=0; i<activeBlock.length; i++){  
                if(activeBlock[i].y==0){  
                    return false;  
                }  
                if(!canFill(activeBlock[i].x, activeBlock[i].y-1)){  
                    return false;  
                }  
            }  
            return true;  
        }  

//右移 
        function moveRight(){  
            if(checkRight()){  
                clear();  
                for(var i=0; i<4; i++){  
                    activeBlock[i].y = activeBlock[i].y + 1;  
                }  
                draw();  
            }  
        }  

//检查右边界 
        function checkRight(){  
            for(var i=0; i<activeBlock.length; i++){  
                if(activeBlock[i].y==9){  
                    return false;  
                }  
                if(!canFill(activeBlock[i].x, activeBlock[i].y+1)){  
                    return false;  
                }  
            }  
            return true;  
        }  

        //旋转
function spin(){  
            var tBlock = new Array(4);  
            for(var i=0; i<4; i++){  
                tBlock[i] = {x:0, y:0};  
            }  
//中心坐标         
            var cx = Math.round((activeBlock[0].x + activeBlock[1].x + activeBlock[2].x + activeBlock[3].x)/4);  
            var cy = Math.round((activeBlock[0].y + activeBlock[1].y + activeBlock[2].y + activeBlock[3].y)/4);  


            for(var i=0; i<4; i++){  
                tBlock[i].x = cx+cy-activeBlock[i].y; 
                tBlock[i].y = cy-cx+activeBlock[i].x; 
            }  
            //旋转后是否合法. 
            for(var i=0; i<4; i++){  
                if(!canFill(tBlock[i].x,tBlock[i].y)){ 
                    return; 
                } 
            } 
            //如果合法, 擦除 
            clear();  
            //对activeBlock重新赋值. 
            for(var i=0; i<4; i++){  
                activeBlock[i].x = tBlock[i].x;  
                activeBlock[i].y = tBlock[i].y;  
            } 
            //重画. 
            draw();  
        }  
       
       
      
        //检查方格是否合法 
        function canFill(x, y){  
            if(x>17||x<0||y>9||y<0){  
                return false;  
            }  
            if(board[x][y]==1){  
                return false;  
            }  
            return true;  
        }  
         //擦除 
        function clear(){  
            for(var i=0; i<4; i++){  
                tbl.rows[activeBlock[i].x].cells[activeBlock[i].y].style.backgroundColor="white";  
            }  
        }  
        
//绘活动方块 
        function draw(){  
            for(var i=0; i<4; i++){  
                tbl.rows[activeBlock[i].x].cells[activeBlock[i].y].style.backgroundColor="red"; 
            }  
        } 

        //更新board数组 
        function updateBoard(){  
            for(var i=0; i<4; i++){  
                board[activeBlock[i].x][activeBlock[i].y]=1;  
            }  
        } 

        //消行 
        function deleteLine(){ 
            var lines = 0; 
            for(var i=0; i<18; i++){

                for(var j=0; j<10; j++){ 
                    if(board[i][j]==0){ 
                        break; 
                    } 
                } 
                if(j==10){ 
                    lines++; 
                    if(i!=0){ 
                        for(var k=i-1; k>=0; k--){ 
                            board[k+1] = board[k]; 
                        } 
                    } 
                    board[0] = createBlankLine(); //产生一个空白行
                } 
            } 
            return lines; 
        } 

        //擦除整个面板 
        function clearBoard(){ 
            for(var i=0; i<18; i++){ 
                for(var j=0; j<10; j++){ 
                    tbl.rows[i].cells[j].style.backgroundColor = "white"; 
                } 
            } 
        } 

        //重绘整个面板 
        function drawBoard(){ 
            for(var i=0;i<18;i++){ 
                for(var j=0; j<10; j++){  
                  if(board[i][j]==1){ 
                    tbl.rows[i].cells[j].style.backgroundColor = "red"; 
                  } 
                }  
            }  
        } 

        //产生一个空白行. 
        function createBlankLine(){ 
            var line = new Array(10); 
            for(var i=0; i<10; i++){ 
                line[i] = 0; 
            } 
            return line; 
        } 

        //更新分数
        function updateScore(){
if(document.all){  
document.getElementById("score").innerText = " " + score; 

else{  
document.getElementById("score").textContent =" " + score;  
}
        }
        
//键盘控制 
        function keyDown(e){  
            if(status!=1){ 
                return; 
            }  


var event = window.event || e;

            var k = event.keyCode;
            switch(k){  
                case 37:{ 
                    moveLeft(); 
                    break;  
                }  
                case 38:{ 
                    spin();  
                    break;  
                }  //旋转
                case 39:{  
                    moveRight();  
                    break; 
                }  
                case 40:{  
                    moveDown();  
                    break;  
                }  
            }  
        }  

        //开始 
        function begin(e){ 
                e.disabled = true; 
            status = 1;  
            tbl = document.getElementById("board");  
 tbl1 = document.getElementById("board1");
            if(!createBlock()){ 
                alert("Game over!"); 
                status = 2; 
                return; 
            } 
            draw(); 
            time = setInterval(moveDown,1000); 
        } 
        document.οnkeydοwn=keyDown;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值