闲来无事翻到一个JavaScript写的俄罗斯方块游戏,玩了一会儿觉得挺好,收藏一下。键盘的W、A、S、D对应小键盘上的“↑”、“←”、“↓”、“→”,其中W和“↑”是切换方块形态的。按“回车键”开始或暂停游戏。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>俄罗斯方块-大超小志</title> <script type="text/javascript" language="javascript"> //单元格宽度 var cellwidth = 15; //单元格个数 var cellcount_x = 18 var cellcount_y = 30; //正在掉落的方块的ID var currentDroper = new Array(); //下个掉落的方块ID var nextDorper = new Array(); //预览的方块ID var preDroper = new Array(); //记录黑色单元格集合 var Blacker = new Array(); //方块掉落的速度,数字越大,速度越慢 var speed = 500; //游戏是否开始 var started = false; //游戏状态 var state = 0;//0:未开始;1:进行中;2:暂停;3:结束 //定时器 var timer = null; function createMap() { createTable(0,0,cellcount_x,cellcount_y,document.getElementById("map_div"));//初始化游戏块 document.getElementById("message_div").style.width="180px"; document.getElementById("message_div").style.height=document.getElementById("map_div").offsetHeight-2+"px"; createTable(100,100,104,104,document.getElementById("preview_div"));//初始化预览块 var x = Math.round(cellcount_x / 2); createDroper(x+"_0"); } //绘制表格 function createTable(i,j,x,y,objDiv) { var objtable = document.createElement("table"); objtable.border = "1"; objtable.cellspacing="0" ; objtable.style.height = cellwidth * (y-j) +"px"; objtable.style.width = cellwidth * (x-i) + "px"; var objtbody = document.createElement("tbody"); for(var m = i;m < y;m++) { var objtr = document.createElement("tr"); objtr.id = m; for(var n = j;n < x;n++) { var objtd = document.createElement("td"); objtd.style.border = "gray solid 1px" objtd.id = n + "_" + m; var txt=document.createTextNode(" "); objtd.appendChild(txt); objtr.appendChild(objtd); } objtbody.appendChild(objtr); } objtable.appendChild(objtbody); objDiv.appendChild(objtable); } //数组是否存在某元素 function isExist(array,key) { for(var i = 0;i < array.length;i++) { if(key == array[i]) { return true; } } return false; } //初始化掉落的方块 function createDroper(currentindex) { var x = currentindex.split('_')[0]; var y = currentindex.split('_')[1]; var n = Math.ceil(Math.random() * 4); if(n == 1 && x < 3) { x = x - 0 + 1; } else if(n == 2 && x >= 1) { x = x - 1; } else if(n == 3 && y >= 1) { y = y - 1; } else if(n== 4 && y < 3) { y = y - 0 + 1; } else{} var _id=x +"_"+ y; if(!isExist(nextDorper,_id)) { if(nextDorper.length >= 4) { return nextDorper; } else { nextDorper.push(_id); createDroper(_id); } } else { createDroper(_id); } } //设置游戏时间 function setNowDate() { document.getElementById("nowDate").value = new Date().toLocaleTimeString(); setTimeout("setNowDate()",1000); } //控制方向 function controlDirection(event) { var myEvent = event || window.event; var keycode = myEvent.keyCode; //获取键盘键值 if(keycode != 13 && keycode != 37 && keycode != 65 && keycode != 38 && keycode != 87 && keycode != 39 && keycode != 68 && keycode != 40 && keycode != 83) { return ; } //按enter键开始 if(keycode == 13) { if(started == false) { started = true; state = 1; document.getElementById("tip").innerHTML = "进行中"; preView(); document.getElementById("startDate").value = new Date().toLocaleTimeString(); setNowDate(); Droping(); } else { if(state == 1) { state = 2; window.clearTimeout(timer); document.getElementById("tip").innerHTML = "暂停中"; } else { state = 1; document.getElementById("tip").innerHTML = "进行中"; timer = window.setTimeout("Droping()",speed); } } return; } var oldDroper = currentDroper; clearOld(currentDroper); var temp; //左移动 if(keycode == 37 || keycode == 65) { temp = updateDropingDroper("left"); } //改变方块掉落方向 else if(keycode == 38 || keycode == 87) { temp = currentDroper.toString().split(','); //先算四个点的中心点,则这四个点围绕中心旋转90度。 var cx = Math.round(((temp[0].split('_')[0]-0) + (temp[1].split('_')[0]-0) + (temp[2].split('_')[0]-0) + (temp[3].split('_')[0]-0))/4); var cy = Math.round(((temp[0].split('_')[1]-0) + (temp[1].split('_')[1]-0) + (temp[2].split('_')[1]-0) + (temp[3].split('_')[1]-0))/4); //旋转的主要算法. 可以这样分解来理解。 //先假设围绕源点旋转。然后再加上中心点的坐标。 for(i=0; i<4; i++) { var x =cx+cy-currentDroper[i].split('_')[1]; var y = cy-cx+(currentDroper[i].split('_')[0]-0); temp[i] = x + "_" + y; } } //右移动 else if(keycode == 39 || keycode == 68) { temp = updateDropingDroper("right"); } //加速 else if(keycode == 40 || keycode == 83) { temp = updateDropingDroper("down"); } //检查下个坐标是否合法 if(checkCurrentDroper(temp)) { currentDroper = temp; } else { currentDroper = oldDroper; } paintNew(currentDroper); } //方块掉落 function Droping() { var oldDroper = currentDroper.toString().split(','); clearOld(currentDroper); var temp = updateDropingDroper("down"); if(checkCurrentDroper(temp)) { currentDroper = temp; paintNew(temp); } else { paintNew(oldDroper); getScores(oldDroper); preView(); } timer = window.setTimeout("Droping()",speed); //window.setTimeout("Droping()",speed); } //预览方块 function preView() { if(checkCurrentDroper(nextDorper)) { currentDroper = nextDorper; } else { state = 3; document.getElementById("tip").innerHTML = "已结束"; alert("你输啦 ( ⊙ o ⊙ )"); window.location.href = window.location.href; } currentDroper = nextDorper.toString().split(','); nextDorper = new Array(); clearOld(preDroper); createDroper("0_0"); preDroper = new Array(); for(var i = 0;i < nextDorper.length;i++) { var x = nextDorper[i].split('_')[0]-0+100; var y = nextDorper[i].split('_')[1]-0+100; var x1 = nextDorper[i].split('_')[0]-0+cellcount_x/2; var y1 = nextDorper[i].split('_')[1]; preDroper[i] = x + "_" + y; nextDorper[i] = x1 + "_" + y1; } paintNew(preDroper); } //销分的方法 function getScores(nowDrop) { var rowsId = ""; for(var w = 0;w < nowDrop.length;w++) { if(rowsId.indexOf(nowDrop[w].split('_')[1]+",",0) == -1) { rowsId += nowDrop[w].split('_')[1]+","; } } rowsId = rowsId.substr(0,rowsId.length-1); var rows = rowsId.split(',').sort().reverse(); for(var i = 0;i < rows.length;i++) { var row = document.getElementById(rows[i]).cells; var isfull = true;//记录是否满格了 for(var j = 0;j < row.length;j++) { if(row[j].style.backgroundColor != "black") { isfull = false; break; } } if(isfull) { document.getElementById("TotalScores").value = document.getElementById("TotalScores").value - 0 + 10;//得分 if((document.getElementById("TotalScores").value - 0 )%100 == 0) { speed = speed - 100 > 0 ? speed - 100 : speed /2; document.getElementById("hardnum").value = document.getElementById("hardnum").value - 0 + 1; } if(document.getElementById("TotalScores").value - 700 >= 0) { alert("赢啦,^_^"); state = 3; document.getElementById("tip").innerHTML = "已结束"; window.location.href = window.location.href; } //得分后销掉已满的单元格 for(var k = 0;k < row.length;k++) { row[k].style.backgroundColor = ""; } Blacker = new Array(); isBlack(rows[i]); //将未销掉的向下移动 var oldBlack = Blacker.toString().split(','); for(var l = 0;l < Blacker.length;l++) { var y = (Blacker[l].split('_')[1]- 0) + 1; var x = Blacker[l].split('_')[0] ; Blacker[l] = x + "_" + y; } clearOld(oldBlack); paintNew(Blacker); i -= 1;//销行后继续检查此行是否可继续销 } } } //递归检测所销行上面的方块颜色 function isBlack(trindex) { var y = trindex - 1; if(y >= 0 && y < cellcount_y ) { for(var i = 0;i < cellcount_x;i++) { var x = i; var nextindex = x + "_" + y; if(document.getElementById(nextindex).style.backgroundColor == "black") { Blacker.push(nextindex); } } isBlack(y); } } //清空方块的坐标 function clearOld(oldDroper) { for(var i = 0;i < oldDroper.length;i++) { document.getElementById(oldDroper[i]).style.backgroundColor = ""; } } //绘制方块的坐标 function paintNew(newDroper) { for(var i = 0;i < newDroper.length;i++) { document.getElementById(newDroper[i]).style.backgroundColor = "black"; } } //更新活动方块数组 function updateDropingDroper(direction) { var x,y; var objDorper = new Array(); for(var i = 0;i < currentDroper.length;i++) { if(direction == "left") { x = currentDroper[i].split('_')[0]-1; y = currentDroper[i].split('_')[1]; } else if(direction == "right") { x = currentDroper[i].split('_')[0]-0+1; y = currentDroper[i].split('_')[1]; } else { x = currentDroper[i].split('_')[0]; y = currentDroper[i].split('_')[1] - 0 + 1; } objDorper.push(x + "_" + y); } return objDorper; } //检查方块是否合法 function checkCurrentDroper(droper) { for(var i = 0;i < droper.length;i++) { var x = droper[i].split('_')[0]; var y = droper[i].split('_')[1]; if(x < 0 || x > cellcount_x - 1 || y < 0 || y > cellcount_y - 1) { return false; } if(document.getElementById(droper[i]).style.backgroundColor == "black") { return false; } } return true; } </script> </head> <body onload="createMap()" onkeydown="controlDirection()"> <div style="text-align:center;"> <br/> <table> <tr> <td> <div id="map_div" style="border:gray solid 1px"> </div> </td> <td> <div id="message_div" style="border:gray solid 1px; text-align:center;"> <br/><br/><font color="red"><b>俄罗斯方块</b></font><br/><br/> <div id="preview_div"> </div> <br/> 游戏状态: <span id="tip">未开始</span> <br/> 开始时间: <input type="text" id="startDate" readonly style="width:80px"/><br/><br/> 现在时间: <input type="text" id="nowDate" readonly style="width:80px"/><br/><br/> 所得分数: <input type="text" id="TotalScores" readonly value="0" style="width:50px"/> <br/><br/> 难度系数: <input type="text" id="hardnum" readonly value="1" style="width:50px;"/> <br/><br/> 按enter键控制游戏状态; <br/> 小键盘方向键和 W S A D 控制方向。 </div> </td> </tr> </table> <br/> </div> </body> </html>
有问题可在下方评论留言,或关注“大超小志”微信公众号留言。
标签: javascript 俄罗斯方块 游戏
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
留言评论
如需留言或评论,请在微信中打开此页面。