今天翻看正理代码库时发现了很早以前用JS写过的一个俄罗斯方块,当时刚接触JS没多久,练手的一个小作品。现在看来确实有些幼稚,但是当初完成之后的那种成有感确实让我兴奋了好几天。

<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<head>
<title>Tetris</title>
<script>
var HNum = 14;
var VNum = 17;
var TModulesNum = 8;
var TetrisWidth = 30;
var TimeSpace = 1000;
var BColor = "#FFFFFF";
var FColor = "#FF0000";
var GridFColor = "#DDDDDD";
var GridColor = "#DDDDDD";
var TModules = new Array(TModulesNum);
var Target = 0;
var lock = false;
var TimeStop = false;
var Sqare = new Array(VNum);
var TimeSpaceStart = 1000;
var TimeSpaceStop = 300;
var MainTime = null;
var Score = 0;

//键盘监控
function InitKeydown()
{
document.onkeydown = showKeyDown
}

function showKeyDown(evt)
{
evt = (evt) ? evt : window.event

switch (evt.keyCode)
{
case 37:
MoveLeft();
break;
case 39:
MoveRight();
break;
case 38:
ReMatrix();
break;
case 40:
ModuleQuickDropDown();
break;
case 32:
if(document.getElementById("btnStart").disabled == true)
{
GameStop();
}
else
{
GameStart();
}
break;

}

}

//方块模型垂直和水平方向整序(VH = "V":垂直方向 VH = "H":水平方向 flag = 0:上小下大 flag = 1:上大下小)
function OrderByVH(VH,flag)
{
var temp = "";
for(var i =0;i< 4;i++)
{
for(var j = i + 1;j< 4;j++)
{
var vhi = 0;
var vhj = 0;
if(VH == "V")
{
vhi = Math.round(TModules[Target][i].split("_")[0]);
vhj = Math.round(TModules[Target][j].split("_")[0]);
}
else if(VH == "H")
{
vhi = Math.round(TModules[Target][i].split("_")[1]);
vhj = Math.round(TModules[Target][j].split("_")[1]);
}
if(flag == 0)
{
if(vhi > vhj)
{
temp = TModules[Target][i];
TModules[Target][i] = TModules[Target][j];
TModules[Target][j] = temp;
}
}
else
{
if(vhi < vhj)
{
temp = TModules[Target][i];
TModules[Target][i] = TModules[Target][j];
TModules[Target][j] = temp;
}
}
}
}
}


//方块左移
function MoveLeft()
{
lock = false;
if(lock == false)
{
lock = true;

//检测碰撞
//----------------------------------------------
for(var t = 0;t < 4;t++)
{
var v = Math.round(TModules[Target][t].split("_")[0]);
var h = Math.round(TModules[Target][t].split("_")[1]);

if(h - 1 < 0)
{
lock = false;
return;
}

var checkneed = true;
for(var p = 0;p < 4;p++ )
{
if(p!=t)
{
var pv = Math.round(TModules[Target][p].split("_")[0]);
var ph = Math.round(TModules[Target][p].split("_")[1]);

if( v == pv && ph == h - 1)
{
checkneed = false;
}
}
}

if(v < 0 || h - 1 < 0 || checkneed == false)
{
continue;
}

if(Sqare[v][h - 1] == 1)
{
lock = false;
return;
}
}
//碰撞检测结束
//----------------------------------------------------

//方块左移
//----------------------------------------------------
OrderByVH("H",0); //左整序
for(var i = 0;i < 4;i++)
{
var v = Math.round(TModules[Target][i].split("_")[0]);
var h = Math.round(TModules[Target][i].split("_")[1]);
var len = Math.round(TModules[Target][i].split("_").length);
if(h - 1 >= 0)
{
if(len == 3)
{
TModules[Target][i] = v.toString() + "_" + (h - 1).toString() + "_D";
}
else
{
TModules[Target][i] = v.toString() + "_" + (h - 1).toString();
}
if( v >= 0)
{
var strT = document.getElementById("T" + v.toString() + "_" + (h - 1).toString());
var strF = document.getElementById("T" + v.toString() + "_" + h.toString());
if(strT != null)
{
if(strF != null)
{
strF.style.backgroundColor = BColor;
Sqare[v][h] = 0;
}
strT.style.backgroundColor = FColor;
Sqare[v][h - 1] = 1;
}
}
}
}
//左移结束
//--------------------------------------------------
lock = false;
}
}

//方块右移
function MoveRight()
{
lock = false;
if(lock == false)
{
lock = true;

//检测碰撞
//----------------------------------------------
for(var t = 0;t < 4;t++)
{
var v = Math.round(TModules[Target][t].split("_")[0]);
var h = Math.round(TModules[Target][t].split("_")[1]);

if(h + 1>= HNum)
{
lock = false;
return;
}
var checkneed = true;
for(var p = 0;p < 4;p++ )
{
if(p!=t)
{
var pv = Math.round(TModules[Target][p].split("_")[0]);
var ph = Math.round(TModules[Target][p].split("_")[1]);

if( v == pv && ph == h + 1)
{
checkneed = false;
}
}
}

if(v < 0 || h + 1 >= HNum || checkneed == false)
{
continue;
}

if(Sqare[v][h + 1] == 1)
{
lock = false;
return;
}
}
//碰撞检测结束
//----------------------------------------------------

//方块右移
//----------------------------------------------------
OrderByVH("H",1); //右整序
for(var i = 0;i < 4;i++)
{
var v = Math.round(TModules[Target][i].split("_")[0]);
var h = Math.round(TModules[Target][i].split("_")[1]);
var len = Math.round(TModules[Target][i].split("_").length);
if(h + 1 < HNum)
{
if(len == 3)
{
TModules[Target][i] = v.toString() + "_" + (h + 1).toString() + "_D";
}
else
{
TModules[Target][i] = v.toString() + "_" + (h + 1).toString();
}
if( v >= 0)
{
var strT = document.getElementById("T" + v.toString() + "_" + (h + 1).toString());
var strF = document.getElementById("T" + v.toString() + "_" + h.toString());
if(strT != null)
{
if(strF != null)
{
strF.style.backgroundColor = BColor;
Sqare[v][h] = 0;
}
strT.style.backgroundColor = FColor;
Sqare[v][h + 1] = 1;
}
}
}
}
//右移结束
//--------------------------------------------------
lock = false;
}
}

//快速下落函数
function ModuleQuickDropDown()
{
while(true&&lock!=true)
{
lock = true;
//检测碰撞
//----------------------------------------------
for(var t = 0;t < 4;t++)
{
var v = Math.round(TModules[Target][t].split("_")[0]);
var h = Math.round(TModules[Target][t].split("_")[1]);
var checkneed = true;
for(var p = 0;p < 4;p++ )
{
if(p!=t)
{
var pv = Math.round(TModules[Target][p].split("_")[0]);
var ph = Math.round(TModules[Target][p].split("_")[1]);

if( v + 1 == pv && ph == h)
{
checkneed = false;
}
}
}

if(v + 1 < 0 || checkneed == false)
{
continue;
}

if(v + 1 >= VNum || Sqare[v + 1][h] == 1)
{
if(v + 1 == 0)
{
lock = false;
GameOver();
return;
}
ReLines();
GetTModule();
lock = false;
return;
}
}
//碰撞检测结束
//----------------------------------------------------

//方块下落
//----------------------------------------------------
OrderByVH("V",1); //下整序
for(var i = 0;i < 4;i++)
{
var v = Math.round(TModules[Target][i].split("_")[0]);
var h = Math.round(TModules[Target][i].split("_")[1]);
var len = Math.round(TModules[Target][i].split("_").length);
if(v + 1 < VNum)
{
if(len == 3)
{
TModules[Target][i] = (v + 1).toString() + "_" + h.toString() + "_D";
}
else
{
TModules[Target][i] = (v + 1).toString() + "_" + h.toString();
}
if( v + 1 >= 0)
{
var strT = document.getElementById("T" + (v + 1).toString() + "_" + h.toString());
var strF = document.getElementById("T" + (v).toString() + "_" + h.toString());
if(v >=0)
{
strF.style.backgroundColor = BColor;
Sqare[v][h] = 0;
}
strT.style.backgroundColor = FColor;
Sqare[v + 1][h] = 1;
}
}
}
//下落结束
//--------------------------------------------------
lock = false;
}
}

//方块下落
function ModuleDropDown()
{
if(lock == false)
{
lock = true;

//检测碰撞
//----------------------------------------------
for(var t = 0;t < 4;t++)
{
var v = Math.round(TModules[Target][t].split("_")[0]);
var h = Math.round(TModules[Target][t].split("_")[1]);
var checkneed = true;
for(var p = 0;p < 4;p++ )
{
if(p!=t)
{
var pv = Math.round(TModules[Target][p].split("_")[0]);
var ph = Math.round(TModules[Target][p].split("_")[1]);

if( v + 1 == pv && ph == h)
{
checkneed = false;
}
}
}

if(v + 1 < 0 || checkneed == false)
{
continue;
}

if(v + 1 >= VNum || Sqare[v + 1][h] == 1)
{
if(v + 1 == 0)
{
lock = false;
GameOver();
if(MainTime != null)
{
clearTimeout(MainTime);
}
return;
}
ReLines();
GetTModule();
lock = false;
if(MainTime != null)
{
clearTimeout(MainTime);
}
setTimeout("ModuleDropDown()",TimeSpace);
return;
}
}
//碰撞检测结束
//----------------------------------------------------

//方块下落
//----------------------------------------------------
OrderByVH("V",1); //下整序
for(var i = 0;i < 4;i++)
{
var v = Math.round(TModules[Target][i].split("_")[0]);
var h = Math.round(TModules[Target][i].split("_")[1]);
var len = Math.round(TModules[Target][i].split("_").length);

if(v + 1 < VNum)
{
if(len == 3)
{
TModules[Target][i] = (v + 1).toString() + "_" + h.toString() + "_D";
}
else
{
TModules[Target][i] = (v + 1).toString() + "_" + h.toString();
}
if( v + 1 >= 0)
{
var strT = document.getElementById("T" + (v + 1).toString() + "_" + h.toString());
var strF = document.getElementById("T" + (v).toString() + "_" + h.toString());
if(v >=0)
{
strF.style.backgroundColor = BColor;
Sqare[v][h] = 0;
}
strT.style.backgroundColor = FColor;
Sqare[v + 1][h] = 1;
}
}
}
//下落结束
//--------------------------------------------------
lock = false;
}
MainTime = setTimeout("ModuleDropDown()",TimeSpace);
}

//旋转 待完善……
function ReMatrix()
{
lock = false;
if(lock == false)
{
lock = true;

//矩阵旋转。
//x' = y + a - b;
//y' = -x + a + b;

var v = -1;
var h = -1;
for(var t = 0;t< 4;t++)
{
if(TModules[Target][t].split("_").length == 3)
{
v = Math.round(TModules[Target][t].split("_")[0]);
h = Math.round(TModules[Target][t].split("_")[1]);
break;
}
}
if(v == -1&&h== -1)
{
lock = false;
return;
}

var TempModules = new Array(4);

for(var i = 0;i< 4;i++)
{
var vn = Math.round(TModules[Target][i].split("_")[0]);
var hn = Math.round(TModules[Target][i].split("_")[1]);
var len = Math.round(TModules[Target][i].split("_").length);
if(hn + v - h >= VNum || -vn + v + h < 0|| -vn + v + h >= HNum)
{
lock = false;
return;
}
if(len == 3)
{
TempModules[i] = (hn + v - h).toString() + "_" + (-vn + v + h).toString() + "_D";
}
else
{
TempModules[i] = (hn + v - h).toString() + "_" + (-vn + v + h).toString();
}
}

for(var i = 0;i< 4;i++)
{
var v1 = Math.round(TempModules[i].split("_")[0]);
var h1 = Math.round(TempModules[i].split("_")[1]);
var isorg = false;
if(v1 < 0)
{
continue;
}
for(var j = 0;j<4;j++)
{
if(TempModules[i] == TModules[Target][j])
{
isorg = true;
}
}
if(Sqare[v1][h1] == 1&&isorg == false)
{
lock = false;
return;
}
}

for(var i = 0;i< 4;i++)
{

var vn = Math.round(TModules[Target][i].split("_")[0]);
var hn = Math.round(TModules[Target][i].split("_")[1]);
TModules[Target][i] = TempModules[i];
if(vn >= 0)
{
var strT = document.getElementById("T" + vn.toString() + "_" + hn.toString());
strT.style.backgroundColor = BColor;
Sqare[vn][hn] = 0;
}
}

for(var i = 0;i< 4;i++)
{
var vn = Math.round(TempModules[i].split("_")[0]);
var hn = Math.round(TempModules[i].split("_")[1]);
if(vn >= 0)
{
var strN = document.getElementById("T" + vn.toString() + "_" + hn.toString());
strN.style.backgroundColor = FColor;
Sqare[vn][hn] = 1;
}
}
lock = false;
}

}

//消行
function ReLines()
{
var count = 0;
var end = false;
while(end == false)
{
for(var i = VNum - 1;i >= 0 ;i--)
{
for(var j = 0;j< HNum;j++)
{
count += Sqare[i][j];
}
if(count < HNum)
{
count = 0;
if(i == 0)
{
end = true;
}
continue;
}

Score += 1;
if(TimeSpace - 10 > TimeSpaceStop)
{
TimeSpace -= 10;
}
document.getElementById("txtScore").value = "Score : " + Score.toString();
document.getElementById("txtSpeed").value ="Speed : " + TimeSpace.toString() + "毫秒";
count = 0;
for(var ii = i - 1;ii >= 0;ii--)
{
for(var j = 0;j< HNum;j++)
{
Sqare[ii + 1][j] = Sqare[ii][j];
var strT = document.getElementById("T" + (ii + 1).toString() + "_" + j.toString());
var strN = document.getElementById("T" + ii.toString() +"_" + j.toString());
strT.style.backgroundColor = strN.style.backgroundColor;
}
}
if(i==0)
{
end = true;
}
break;
}
}

}

//游戏开始
function GameStart()
{
ModuleDropDown();
document.getElementById("btnStart").disabled = true;
document.getElementById("btnStop").disabled = false;
}

//游戏暂停
function GameStop()
{
document.getElementById("btnStart").disabled = false;
if(MainTime != null)
{
clearTimeout(MainTime);
}
}

//游戏结束
function GameOver()
{
for(var i = 0;i< VNum ;i++)
{
for(var j = 0;j< HNum;j++)
{
document.getElementById("T" + i.toString() + "_" + j.toString()).style.backgroundColor = FColor;
}
}
alert("Game Over !");
for(var i = 0;i< VNum ;i++)
{
for(var j = 0;j< HNum;j++)
{
document.getElementById("T" + i.toString() + "_" + j.toString()).style.backgroundColor = BColor;
}
}

if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;
Score = 0;
document.getElementById("txtScore").value = "Score : 0";
document.getElementById("txtSpeed").value ="Speed : " + TimeSpace.toString() + "毫秒";
document.getElementById("btnStart").disabled = false;
}

//游戏参数初始化
function MainFunction()
{
InitialPanel();
InitialSqare();
InitialTModules();
GetTModule();
InitKeydown()
}

//初始化面板
function InitialPanel()
{
var vwidth = HNum * TetrisWidth + HNum - 1;
var vheight = VNum * TetrisWidth + VNum - 1;
var contentdivstr = "<div style=\"width:";
contentdivstr += (vwidth + 2).toString();
contentdivstr += "px;height:";
contentdivstr += (vheight + 2).toString();
contentdivstr +=";\"><div id=\"TetrisContent\" style=\"width:100%; height:100%; border:solid 1px #000000; position:relative;\"></div></div>";
document.getElementById("contentdiv").innerHTML = contentdivstr;

var BorderLines = "";
for(var i = 1;i< VNum;i++)
{
BorderLines += "<div style =\"position:absolute;top:";
BorderLines += (i * TetrisWidth + (i - 1)).toString();
BorderLines += "px;left:0px;width:";
BorderLines += vwidth.toString();
BorderLines += "px;height:1px;background-color:";
BorderLines += GridColor +";\"></div>";
}

for(var i = 1;i< HNum;i++)
{
BorderLines += "<div style =\"position:absolute;left:";
BorderLines += (i * TetrisWidth + (i - 1)).toString();
BorderLines += "px;top:0px;height:";
BorderLines += vheight.toString();
BorderLines += "px;width:1px;background-color:";
BorderLines += GridColor +";\"></div>";
}

var VHDots = "";

for(var p = 0 ;p < VNum ;p++)
{
for(var k = 0;k< HNum; k++)
{

VHDots += "<div id=\"T"
VHDots += p.toString() + "_" + k.toString();
VHDots +="\" style=\"LEFT: ";
VHDots += (k * TetrisWidth + k ).toString() + "px; WIDTH:";
VHDots += (TetrisWidth).toString() + "px; POSITION: absolute; TOP: ";
VHDots += (p * TetrisWidth + p ).toString() + "px; HEIGHT: ";
VHDots += (TetrisWidth).toString() + "px;background-color:";
VHDots += BColor + ";\" ></div>";
}
}
document.getElementById("TetrisContent").innerHTML = BorderLines + VHDots;
document.getElementById("txtScore").value = "Score : 0";
document.getElementById("txtSpeed").value ="Speed : " + TimeSpace.toString() + "毫秒";
document.getElementById("btnStart").disabled = false;
document.getElementById("btnStop").disabled = false;
}

//初始化方块位置矩阵
function InitialSqare()
{
for(var i = 0;i < VNum;i++)
{
Sqare[i] = new Array(HNum);
for( var j = 0;j < HNum;j++)
{
Sqare[i][j] = 0;
}
}
}

//初始化方块模型
function InitialTModules()
{
var sh = Math.round((HNum - 1) / 2) - 2;
TModules[0] = new Array("-1_" + sh.toString(),"-1_" + (sh + 1).toString() + "_D","-1_" + (sh + 2).toString(),"-1_" + (sh + 3).toString()); //横条
sh = Math.round((HNum -1) / 2);
TModules[1] = new Array("-1_" + sh.toString(),"-2_" + sh.toString(),"-3_" + sh.toString() + "_D","-4_" + sh.toString()); //竖条
sh = Math.round((HNum - 1) / 2) - 1;
TModules[2] = new Array("-1_" + sh.toString() + "_D","-1_" + (sh + 1).toString(),"-2_" + sh.toString(),"-3_" + sh.toString()); //右L
TModules[3] = new Array("-1_" + sh.toString(),"-1_" + (sh + 1).toString() + "_D","-2_" + (sh + 1).toString(),"-3_" + (sh + 1).toString()); //左L
sh = Math.round((HNum - 1) / 2);
TModules[4] = new Array("-1_" + (sh + 1).toString(),"-1_" + sh.toString() + "_D","-2_" + sh.toString(),"-2_" + (sh - 1).toString()); //左Z
TModules[5] = new Array("-1_" + (sh - 1).toString(),"-1_" + sh.toString() + "_D","-2_" + sh.toString(),"-2_" + (sh + 1).toString()); //右Z
sh = Math.round((HNum - 1) / 2);
TModules[6] = new Array("-1_" + (sh - 1).toString(),"-1_" + sh.toString() + "_D","-1_" + (sh + 1).toString(),"-2_" + sh.toString()); //上凸
TModules[7] = new Array("-1_" + sh.toString(),"-1_" + (sh + 1).toString(),"-2_" + sh.toString(),"-2_" + (sh + 1).toString());//
}

//获得随机模型
function GetTModule()
{
Target = Math.floor(Math.random()*TModulesNum + 1) - 1;
InitialTModules();
}
function ChangeV(dis)
{
if(VNum + dis>=10&&VNum + dis<=20)
{
VNum += dis;
InitialPanel();

if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;

}
}

//隐藏显示网格
function GridOn(flag)
{

if(document.getElementById("btngrid").value=="无网格")
{
document.getElementById("btngrid").value = "网格";
GridColor = BColor;
}
else
{
document.getElementById("btngrid").value = "无网格";
GridColor = GridFColor;
}
InitialPanel();
if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;
}

//横向增加减少网格
function ChangeH(dis)
{
if(HNum + dis>=10 && HNum + dis<=26)
{
HNum += dis;
InitialPanel();

if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;
}
}
function CreateBtns()
{
var clr = new Array('FF','C0','A0','80','60','40','20','00');
var bgcolorsele = document.getElementById("bgcolors");
var fcolorssele = document.getElementById("fcolors");
var seloption = null;
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
for (k=0;k<8;k++)
{
seloption = new Option("#" + clr[i]+clr[j]+clr[k],"#" + clr[i]+clr[j]+clr[k]);
seloption.style.backgroundColor = "#"+clr[i]+clr[j]+clr[k];

if("#"+clr[i]+clr[j]+clr[k] == BColor)
{
seloption.selected = true;
bgcolorsele.style.backgroundColor = "#"+clr[i]+clr[j]+clr[k];
}

bgcolorsele.options[bgcolorsele.length] = seloption;

seloption = new Option("#" + clr[i]+clr[j]+clr[k],"#" + clr[i]+clr[j]+clr[k]);
seloption.style.backgroundColor = "#"+clr[i]+clr[j]+clr[k];
if("#"+clr[i]+clr[j]+clr[k] == FColor)
{
seloption.selected = true;
fcolorssele.style.backgroundColor = "#"+clr[i]+clr[j]+clr[k];
}
fcolorssele.options[fcolorssele.length] = seloption;
}
}
}
}

function BColorChange()
{
var bgcolorsel = document.getElementById("bgcolors");
BColor = bgcolorsel.options[bgcolorsel.selectedIndex].value;
bgcolorsel.style.backgroundColor = BColor;
InitialPanel();

if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;
}

function FColorChange()
{
var fcolorsel = document.getElementById("fcolors");
FColor = fcolorsel.options[fcolorsel.selectedIndex].value;
fcolorsel.backgroundColor = FColor;
InitialPanel();

if(MainTime != null)
{
clearTimeout(MainTime);
}
InitialSqare();
InitialTModules();
GetTModule();
lock = false;
}

</script>
</head>
<body onLoad="MainFunction();CreateBtns();">
<div>
<div style="margin-bottom:4px;">
<input type="button" value="横向扩展" onClick="ChangeH(1)" />
<input type="button" value="横向收缩" onClick="ChangeH(-1)" />
<input type="button" value="纵向扩展" onClick="ChangeV(1)" />
<input type="button" value="纵向收缩" onClick="ChangeV(-1)" />
<input type="button" id="btngrid" value="无网格" onClick="GridOn()" />

</div>

<div style="margin-bottom:4px;">
背景色:
<select id="bgcolors" style="background-color:#FFFFFF;" onChange="BColorChange()">
</select>
前景色
<select id="fcolors" style="background-color:#FFFFFF;" onChange="FColorChange()">
</select>
</div>
<div style="margin-bottom:4px;">
<input type="text" id="txtScore" style="border:none; text-align:center;" value="" />
<input type="text" id="txtSpeed" style="border:none; text-align:center;" value="" />
<input type="button" id="btnStart" onClick="GameStart()" value="开始" />
<input type="button" id="btnStop" onClick="GameStop()" value="停止" />
</div>
<div id="contentdiv" style="height:auto; " > </div>
</div>
</body>
</html>

这里不做详细讲解了,有兴趣的可以自己读一下代码,注释比较清楚。

拷贝代码可直接运行





posted on 2011-10-31 23:02  漠漠轻寒  阅读(1088)  评论(0编辑  收藏  举报