JavaScript俄罗斯方块的写法(代码教程)
程序员文章站
2022-06-30 09:35:15
最近研究了一个“俄罗斯方块”的写法,设计的很巧妙,代码展示如下:
最近研究了一个“俄罗斯方块”的写法,设计的很巧妙,代码展示如下:
<!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"> <p id="lay" style="z-index:1; left:23px; position:absolute; top:10px"> <table id="tabarea" class="rect" cellpadding="0" cellspacing="1"> </table> </p> <p 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> </p> <p 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> </p> <p id="layer1" style="position:absolute;z-index:2; left:331px; top: 465px;height:36px;"> <input onclick="gamestart();" type="button" value="开始" id="btnstart"> </p> </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>
时间关系,下周分析。