【JavaScript】(二)俄罗斯方块

    最近研究了一个“俄罗斯方块”的写法,设计的很巧妙,代码展示如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
<title>我的小方块!</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
	/*程序中所用到的样式.*/
	.Rect {
	border: 2px solid #FFFFFF;
	width: 265;
	height: 575;
}
.td {
	border: 1px double #FFFFFF;
}
.stop {
	border: 1px double #FFFFFF;
}
.smallRect {
	border: 2px solid #FFFFFF;
	width: 89;
	height: 50;
}
.smallTd {
	border: 1px double #FFFFFF;
}
-->
</style>
</head>
	<body bgcolor="#000000">
		<div id="lay" style="Z-INDEX:1; LEFT:23px; POSITION:absolute; TOP:10px">
			<table id="tabArea" class="rect" cellpadding="0" cellspacing="1">
			</table>
		</div>
		
		<div id="View" style="Z-INDEX:3; LEFT:314px; POSITION:absolute; TOP:16px"> 
			<table id="tabView" border="0" cellpadding="1" cellspacing="1" class="smallRect">
				<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>
				<tr>
					<td> </td>
					<td> </td>
					<td> </td>
					<td> </td>
				</tr>
			</table>
		</div>
		
		<div id="layScore" style="position:absolute; left:326px; top:390px; z-index:4">
		  <table border="0" cellspacing="0" cellpadding="0">
			<tr> 
			  <td style="color:#ffffff">分数:</td>
			  <td id=tdScore align="center" style="color:#ff0000">0</td>
			</tr>
		  </table>
		</div>
	
		<div id="Layer1" style="POSITION:absolute;Z-INDEX:2; left:331px; top: 465px;height:36px;"> 
		  <INPUT onclick="GameStart();" type="button" value="开始" id="btnStart">
		</div>
</body>
</html>
<script language="javascript">
	var RECTROW = 20;     				//定义24行.大方块
	var RECTCOL = 10;						//定义10列大方块
	var arrView = new Array(6);       //右上方小
	var hInter;                        //InterVal 句柄.
	var val = 600;                      //延时.

	var hFlash;
	var flashVal = 50;                  //消层时闪的频率.
	var flashCount = 5;                  //闪的次数.
	var minR=0;                        //当前含有实体的最低层.

	var BGCOLOR='#0000ff';              //方块颜色
	var INITPOS = 4;                     //新实体位置.

	var reCur;							//当前实体序号.
	var reNext = Math.round(Math.random()*5);;
	var arrMove = new Array();       //当前运动的方块
	var blnBottom = true;           //是否到底部
	var transfer = 1;             //变化的方向.
	var arrC = new Array();

	Load();

	function $(id) {return document.getElementById(id);}

	//---------------------------------按键及各种事件--------------------

	// 游戏中所用到的事件函数..
	function GameStart()
	{	
		if($('btnStart').value == '开始')
		{
			hInter = window.setInterval(Run,val);
			document.onkeydown = OnKeyDown;
			$('btnStart').value = '暂停';
		}
		else
		{
			$('btnStart').value = '开始';
			window.clearInterval(hInter);
			document.onkeydown = null;
		}
	}
	function OnKeyDown(e)
	{ 
		var code = 0;
		if(e)
			code = e.keyCode;		//ff浏览器
		else
			code = window.event.keyCode;	//IE
		 
		switch(code)
		{
			case 37:       //Left Arrow
				LeftDown();
				break;
			case 39:       //right Arrow
				RightDown();
				break;
			case 38:       //top Arrow            -->变化
				TopDown();        
				break;
			case 40:        //bottom Arrow;
				 BottomDown();
				 break;
		}
	}
	function LeftDown()
	{
		for(var i =0;i<arrMove.length;i++)
		{	
			var r = arrMove[i][0]-1;
			var c = arrMove[i][1]-1;
			
			if( c+1==0 || $('tabArea').rows[r].cells[c].className.toLowerCase() == 'stop' ) return;     //如果到边		
		}	
		Clear();
		blnBottom = false;
		for(var i=0;i<arrMove.length;i++)
		{	
			var r = arrMove[i][0]-1;
			var c = --arrMove[i][1];
			$('tabArea').rows[r].cells[c].bgColor = BGCOLOR;
			$('tabArea').rows[r].cells[c].className = 'td';		
			
			if(r+1==RECTROW || $('tabArea').rows[r+1].cells[c].className.toLowerCase()=='stop')
			{   			
				blnBottom = true;			
			}				
		}	
	}
	function RightDown()
	{
		for(var i =0;i<arrMove.length;i++)
		{
			var r = arrMove[i][0]-1;
			var c = arrMove[i][1]+1;		
			if(c==RECTCOL || $('tabArea').rows[r].cells[c].className.toLowerCase() == 'stop' )return;              //如果到边.			
		}
		Clear();
		blnBottom = false;
		for(var i=0;i<arrMove.length;i++)
		{	
			var r = arrMove[i][0]-1;
			var c = ++ arrMove[i][1];
			$('tabArea').rows[r].cells[c].bgColor=BGCOLOR;
			$('tabArea').rows[r].cells[c].className='td';		
			
			if(r+1==RECTROW || $('tabArea').rows[r+1].cells[c].className.toLowerCase()=='stop')
			{   			
				blnBottom = true;			
			}						
		}
	}
	function TopDown()             //默认为顺时针转.
	{		
		if(blnBottom)return;
		var oR = arrMove[1][0] - 1;        //中心元素.
		var oC = arrMove[1][1];
		
		if(AnyRectChange() == 0) return;
		blnBottom = false;
		for(var i=0;i<arrMove.length;i++)
		{		
			var r = arrMove[i][0] - 1;
			var c = arrMove[i][1];				
			//显示变化..		
			var nc = (c - oC);
			var nr = (r - oR);
			r = oR + nc * transfer;
			c = oC - nr * transfer;		
			
			if((r+1) >= RECTROW || r < 0 || c < 0 || c >= RECTCOL || $('tabArea').rows[r].cells[c].className == 'stop') return;
			if($('tabArea').rows[r+1].cells[c].className == 'stop') blnBottom = true;
		}	
		
		Clear();	 

		for(var i=0;i<arrMove.length;i++)
		{		
			var r = arrMove[i][0] - 1;
			var c = arrMove[i][1];				
			//显示变化..		
			var nc = (c - oC);
			var nr = (r - oR);
			r = oR + nc * transfer;
			c = oC - nr * transfer;		
			
			$('tabArea').rows[r].cells[c].bgColor = BGCOLOR;
			$('tabArea').rows[r].cells[c].className = 'td';		
			
			arrMove[i][0] = r + 1;
			arrMove[i][1] = c;		
		}	
	}
	function BottomDown()
	{
		if(!blnBottom)
		{
			Runing();
		}
	}

	//-----------------------------------------------自定义函数---------------------------

	// 所用函数

	//初始场景..
	function Load()
	{		
		var tabRoot = $('tabArea');		
		for(var i=0;i<RECTROW;i++)
		{
			var row = tabRoot.insertRow(tabRoot.rows.length);		
			for(var j=0;j<RECTCOL;j++)
			{						
				var cell = row.insertCell(j);
				cell.innerHTML = ' ';									
			}		
		}		
		InitSmallRect();
	}
	//初始各元素.
	function InitSmallRect()
	{
		//每实体第2块为中心元素
		arrView[0] = new Array(new Array(0,1),new Array(1,1),new Array(2,1),new Array(2,2));         // L
		arrView[1] = new Array(new Array(0,1),new Array(1,1),new Array(2,1),new Array(3,1));         // |
		arrView[2] = new Array(new Array(0,1),new Array(0,2),new Array(1,1),new Array(1,2));         // 田
		arrView[3] = new Array(new Array(0,1),new Array(1,1),new Array(2,1),new Array(1,2));		 // 山
		arrView[4] = new Array(new Array(0,0),new Array(0,1),new Array(1,1),new Array(1,2));	     // Z
		arrView[5] = new Array(new Array(0,2),new Array(0,1),new Array(1,1),new Array(1,0));         // S	
	}
	function ViewSmallRect()
	{	
		reCur = reNext;
		reNext = Math.round(Math.random()*5);				//随机生成一实体.
		
		for(var i=0;i<arrView[reCur].length;i++)
		{			               //先清空		
			var r = arrView[reCur][i][0];
			var c = arrView[reCur][i][1];
			if(reCur != 1) r+=1;
			var cel = $('tabView').rows[r].cells[c];
			cel.bgColor='';
			cel.className = '';
		}
		
		for(var i=0;i<arrView[reNext].length;i++)
		{			         		
			var r = arrView[reNext][i][0];
			var c = arrView[reNext][i][1];
			if(reNext != 1) r+=1;
			var cel = $('tabView').rows[r].cells[c];
			cel.bgColor=BGCOLOR;
			cel.className = "smallTd";
		}	
	}
	//生成一个新实体.
	function Create()
	{	
		//新建新实体前先保存保存上一个实体的状态	
		for(var i=0;i<arrMove.length;i++)
		{
			var r = arrMove[i][0]-1;
			var c = arrMove[i][1];
			$('tabArea').rows[r].cells[c].className = 'stop';				
		}
		Mark();           //消层及计分.
		ViewSmallRect();
		arrMove = new Array();	
		for(var i=0;i<arrView[reCur].length;i++)
		{		
			arrMove[i] = new Array();	
			arrMove[i][0]=arrView[reCur][i][0];
			arrMove[i][1]=arrView[reCur][i][1] + INITPOS;
		}	
		for(var i=0;i<arrMove.length;i++)  //显示在INITPOS处
		{
			var r = arrMove[i][0]++;
			var c = arrMove[i][1];	
			
			if($('tabArea').rows[r].cells[c].className=='stop')
			{
				alert('Game Over!');          //游戏结束.
				window.clearInterval(hInter);
				return;
			}							
					
			$('tabArea').rows[r].cells[c].bgColor=BGCOLOR;
			$('tabArea').rows[r].cells[c].className = 'td';
		}
		blnBottom = false;
	}
	function Runing()
	{	
		for(var i=0;i<arrMove.length;i++)
		{			
			var r = arrMove[i][0];
			var c = arrMove[i][1];
			if(r >= RECTROW || $('tabArea').rows[r].cells[c].className.toLowerCase()=='stop') 
			{
				blnBottom = true;		
				return;
			}
		}
		
		Clear();
		for(var i=0;i<arrMove.length;i++)
		{			
			var r = arrMove[i][0]++;
			var c = arrMove[i][1];				
			var col = $('tabArea').rows[r].cells[c];
			col.bgColor=BGCOLOR;
			col.className = 'td';					
		}	
	}
	//游戏运行..
	function Run()
	{
		
		if(blnBottom)
		{
			Create();
		}
		else
		{
			Runing();
		}	
	}
	//清除
	function Clear()
	{
		for(var k=0;k<arrMove.length;k++)
		{
			var r = arrMove[k][0]-1;
			var c = arrMove[k][1];
			$('tabArea').rows[r].cells[c].bgColor='';
			$('tabArea').rows[r].cells[c].className='';				
		}		
	}

	//特殊实体的运行
	function AnyRectChange()
	{
		switch(reCur)
		{
			case 1:       // |
				transfer *= -1;
				break;
			case 2:       // 田
				return 0;
				break;
			case 4:
				transfer *= -1;
				break;
			case 5:
				transfer *= -1;
				break;
		}
	}

	function Mark()
	{	
		arrC = new Array();
		minR = 0;
		for(var i=RECTROW-1;i>=0;i--)
		{
			var full = true;
			var empty = true;
			for(var j=0;j<RECTCOL;j++)
			{
				var td = $('tabArea').rows[i].cells[j];
				if(td.className.toLowerCase() == 'stop') empty = false;
				
				full = (td.className == 'stop') && full			
			}
			if(empty)
			{
				minR = i-1;
				break;
			}         //如果是空行.
			if(full)arrC.push(i);
		}
		if(arrC.length > 0)
		{
			hFlash = window.setInterval(WillClear,flashVal);       //闪光
			flashCount = 5;
		}
	}
	//闪光..
	function WillClear()
	{	
		for(var i=0;i<arrC.length;i++)
		{
			for(var j=0;j<RECTCOL;j++)
			{
				if($('tabArea').rows[arrC[i]].cells[j].bgColor.toLowerCase() == BGCOLOR.toLowerCase())
				{
					$('tabArea').rows[arrC[i]].cells[j].bgColor = '#ffffff';
				}
				else
				{
					$('tabArea').rows[arrC[i]].cells[j].bgColor = BGCOLOR;
				}
			}
		}
		flashCount --;
		if(flashCount <= 0) 
		{
			ClearFull(minR);
			window.clearInterval(hFlash);
		}
	}
	//消去把满的层.
	function ClearFull(minRow)
	{   	
		var arrFull = arrC;
		for(var i=0;i<arrFull.length;i++)
		{
			var r = arrFull[i]+i;
			for(var j=0;j<RECTCOL;j++)
			{
				$('tabArea').rows[r].cells[j].className = '';
				$('tabArea').rows[r].cells[j].bgColor = '';
				for(var k=r-1;k>minRow;k--)
				{
					if($('tabArea').rows[k].cells[j].className == 'stop')           //上面的行向下移.
					{
						$('tabArea').rows[k].cells[j].className = '';
						$('tabArea').rows[k].cells[j].bgColor = '';
						
						$('tabArea').rows[k+1].cells[j].className = 'stop';
						$('tabArea').rows[k+1].cells[j].bgColor = BGCOLOR;
					}
				}		
			}
			minRow++;
		}
		//计分.
		switch(arrFull.length)
		{
			case 1:
				$('tdScore').innerHTML = Number($('tdScore').innerHTML) + 100;
				break;
			case 2: 
				$('tdScore').innerHTML = Number($('tdScore').innerHTML) + 300;
				break;
			case 3:
				$('tdScore').innerHTML = Number($('tdScore').innerHTML) + 500;
				break;
			case 4:
				$('tdScore').innerHTML = Number($('tdScore').innerHTML) + 800;
				break;
		}
	}
</script>
     时间关系,下周分析。

猜你喜欢

转载自blog.csdn.net/u013047584/article/details/79243477