使用JS代码实现俄罗斯方块游戏
程序员文章站
2022-12-31 23:06:35
简单的js俄罗斯方块游戏源码,先给大家展示下效果图,如果大家感觉不错,请参考实现代码,
效果图:
代码如下,复制即可使用:
&l...
简单的js俄罗斯方块游戏源码,先给大家展示下效果图,如果大家感觉不错,请参考实现代码,
效果图:
代码如下,复制即可使用:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>使用js实现俄罗斯方块游戏</title> <style type="text/css"> .mainframe { border: 1px solid burlywood; margin: 10px auto; position: relative; background-color: silver; } .mainframediv { float: left; margin: 1px; position: absolute; /*z-index: -1;*/ } .smalldiv { margin: 1px; position: absolute; } .smalldivblack { /*float: left;*/ margin: 1px; /*margin: 1px;*/ position: absolute; /*z-index: 2;*/ } #tetris{ width: 50%; margin: 0 auto; padding: 0; /*border: 1px solid silver;*/ } #tetris:after{ content: ""; display: block; clear: both; } #control{ float: left; border: 1px solid silver; width: 150px; height: 578px; margin-top: 10px; margin-left: 20px; padding-top: 30px; font-size: 24px; font-weight: 400; color: blue; text-align: center; } #level,#regame{ width: 100px; height: 30px; border: 1px solid blue; font-size: 16px; color: red; font-weight: 300; } #control p{ margin-top: 200px; } #regame{ margin-top: 100px; font-weight: 600; background-color: azure; } #tfrime{ float: left; } #info{ float: left; border: 1px solid silver; width: 150px; height: 578px; margin: 10px auto; padding-top: 30px; text-align: center; color: blue; font-size: 24px; font-weight: 400; } #nextfigure{ width: 100px; height: 100px; background-color: silver; margin: 0 auto; margin-bottom: 100px; position: relative; } .drawdiv{ background-color: red; margin: 1px; border: 1px solid silver; position: absolute; } </style> <!-- 此处需要自己修改js路径 --> <script src="js/gameframe.js" type="text/javascript" charset="utf-8"></script> <script src="js/graph.js" type="text/javascript" charset="utf-8"></script> <script src="js/index.js" type="text/javascript" charset="utf-8"></script> </head> <body onload="initgame()"> <div id="tetris"> <div id="control"> 难度: <div><select id="level" onchange="changespeed()"> <option value="1000">简单 <option value="500">一般 <option value="200">困难 </select></div> <input type="button" id="regame" value="重 新 开 始" onclick="regame()"> <p> ↑:变换<br> ←:左移<br> →:右移<br> ↓:加速<br> </p> </div> <div id="tfrime"></div> <div id="info"> 下一个图形: <div id="nextfigure"> </div> <div>分数:<span id="score">0</span></div> </div> </div> <div style="text-align:center;margin:10px 0; font:normal 14px/24px 'microsoft yahei';"> <p>适用浏览器:360、firefox、chrome、safari、opera、傲游、搜狗、世界之窗. 不支持ie8及以下浏览器。</p> </div> </body> </html>
gameframe.js
function gameframe(unit,row,col) { //单位的像素 this.unit = unit; //横向单位个数(列),,(一行的个数) this.row = row; //纵向单位个数(行),,(一列的个数) this.col =col; //保存页面创建div容器的属性 this.content; //小图形 this.samlldiv; //定时器id this.intervalid; //速度 this.speed =document.getelementbyid("level").value; //速度是否改变 this.changesped=0; //记录每个位置是否有div this.datas=[]; //记录消除行数相应的分数 this.score=[0,100,300,600,1000] //记录当前的图形的下标 this.now; //记录下一个图形的下标 this.next; //记录当前的图形的颜色 this.nowcolor; //记录下一个图形的颜色 this.nextcolor; //保存7种图形相对坐标的数组 this.arr = "0,1,0,2,1,2,2,2;0,1,1,1,1,2,2,2;0,1,0,2,1,1,2,1;0,2,1,1,1,2,2,1;1,0,1,1,1,2,1,3;1,1,1,2,2,1,2,2;1,1,2,0,2,1,2,2".split(";"); //保存小方块的颜色 this.color=["red","blue","green","yellow","#00ffff","#930093","#f80000","#984b4b"]; //初始化容器div this.init = function() { //创建div var div = document.createelement("div"); //设置div的宽度 div.style.width = (this.unit*this.row)+"px"; //设置div的高度 div.style.height=(this.unit*this.col)+"px"; //设置div的样式 div.classname="mainframe"; div.id="mainframe"; //加入到body中 document.getelementbyid("tfrime").appendchild(div); this.content =div; //保存div的引用 //初始化数组 for(var i=0;i<this.col;i++) //i为行 { for(var j=0;j<this.row;j++){ //j为列 var sdiv = document.createelement("div"); sdiv.classname="mainframediv"; sdiv.style.width = (this.unit - 2) + "px"; sdiv.style.height = (this.unit - 2) + "px"; sdiv.style.left=(j*this.unit)+"px"; sdiv.style.top=(i*this.unit)+"px"; this.content.appendchild(sdiv); this.datas.push(0); } } this.next=math.floor(math.random() * this.arr.length); this.nextcolor=this.color[math.floor(math.random() * this.color.length)]; start(); } this.moveleft = function() { this.samlldiv.moveleft(); } this.moveright = function(){ this.samlldiv.moveright(); } this.change = function(){ this.samlldiv.change(); } this.movedown = function(){ if(this.samlldiv.movedown()) { // for(var i=0;i<this.samlldiv.divs.length;i++) // { // this.content.removechild(this.samlldiv.divs[i]); // } this.samlldiv.rescore(); start(); } } function start() { //将next值传给now this.frame.now=this.frame.next; this.frame.nowcolor=this.frame.nextcolor; //创建小div this.frame.samlldiv=new graph(this.frame); this.frame.samlldiv.init(this.frame.now,this.frame.nowcolor); //绘出下一个图形 this.frame.next=math.floor(math.random() * this.frame.arr.length); this.frame.nextcolor=this.frame.color[math.floor(math.random() * this.frame.color.length)]; draw(); //调用定时器下落 this.frame.intervalid = setinterval(automovedown,this.frame.speed); //判断游戏是否结束 if (this.frame.samlldiv.movedown()){ clearinterval(this.frame.intervalid); alert("游戏结束!"); } } function automovedown() { if(this.frame.samlldiv.movedown()) { this.frame.samlldiv.rescore(); start(); } //改变速度 if(this.frame.changesped){ clearinterval(this.frame.intervalid); this.frame.intervalid = setinterval(automovedown,this.frame.speed); this.frame.changesped=0; } } //速度改变,令changesped值为1 this.changespeed=function(){ this.speed=document.getelementbyid("level").value; this.changesped=1; // alert(this.changesped); } //绘制下一个图形 function draw(){ //清楚原有的图形 var cleardiv=document.getelementsbyclassname("drawdiv"); for(;;){ if(cleardiv.length){ document.getelementbyid("nextfigure").removechild(cleardiv[0]); }else{ break; } } //绘制图形 var smallarr = this.frame.arr[this.frame.next].split(","); for (var i = 0; i < 8; i += 2) { var drawdiv = document.createelement("div"); drawdiv.classname = "drawdiv"; drawdiv.style.backgroundcolor=this.frame.nextcolor; drawdiv.style.width = (this.frame.unit - 2) + "px"; drawdiv.style.height = (this.frame.unit - 2) + "px"; drawdiv.style.top = (((smallarr[i] - 0) * this.frame.unit)+18) + "px"; drawdiv.style.left = (((smallarr[i + 1] - 0) * this.frame.unit)+18) + "px"; document.getelementbyid("nextfigure").appendchild(drawdiv); } } }
graph.js
function graph(frame) { //保存7种图形相对坐标的数组 // var arr = "0,1,0,2,1,2,2,2;0,1,1,1,1,2,2,2;0,1,0,2,1,1,2,1;0,2,1,1,1,2,2,1;1,0,1,1,1,2,1,3;1,1,1,2,2,1,2,2;1,1,2,0,2,1,2,2".split(";"); //保存4个小图形的数组 this.divs = []; //外部容器div的数组 this.parentframe = frame; //图形横纵偏移 this.x = 0; this.y = 0; //记录图形的坐标数组 this.zb = []; //记录消除的行数 this.line=0; //初始化小图形的方法 this.init = function(rand,color) { //计算图形其实坐标的单位 var startleft = (this.parentframe.row - 4) / 2; this.x = startleft; //随机生成图形数组下标 // var rand = math.floor(math.random() * arr.length); //分解图形的坐标 var smallarr = this.parentframe.arr[rand].split(","); this.zb = smallarr; //循环设置小div的 left和top for (var i = 0; i < 8; i += 2) { //创建小div var smalldiv = document.createelement("div"); //设置样式 smalldiv.classname = "smalldiv"; //设置颜色 smalldiv.style.backgroundcolor=color; //定义高宽 smalldiv.style.width = (this.parentframe.unit - 2) + "px"; smalldiv.style.height = (this.parentframe.unit - 2) + "px"; //设置小div的top smalldiv.style.top = ((smallarr[i] - 0) * this.parentframe.unit) + "px"; //设置小div的left smalldiv.style.left = (((smallarr[i + 1] - 0) + startleft) * this.parentframe.unit) + "px"; //保存小div的引用 this.divs.push(smalldiv); //加入到外部容器 document.getelementbyid("mainframe").appendchild(smalldiv); } //执行自动向下移动 //this.parentframe.intervalid = setinterval(automovedown, this.parentframe.speed); } //左移动 this.moveleft = function() { // var canmove = true; // //判断能否左移动 // // for(var i=0;i<this.divs.length;i++) // { // var left=parseint(this.divs[i].style.left); //div目前的left // if(left - this.parentframe.unit <0) //减去一个单位的像素是否小于0 // { // canmove = false; //不能向左移动了 // break; // } // } if (canmove(this.zb, this.x, this.y, this.parentframe, 2)) //可以移动 { this.x -= 1; for (var i = 0; i < this.divs.length; i++) //循环小div,把每个div的left减去一个单位的像素 { var left = parseint(this.divs[i].style.left); this.divs[i].style.left = (left - this.parentframe.unit) + "px"; } } } //右移动 this.moveright = function() { // var canmove = true; // //判断能否右移动 // for(var i=0;i<this.divs.length;i++) // { // var left=parseint(this.divs[i].style.left); // if(left + this.parentframe.unit >=parseint(this.parentframe.content.style.width)) // { // canmove = false; // break; // } // } var temp = canmove(this.zb, this.x, this.y, this.parentframe, 1); // alert(temp); console.log(temp); if (canmove(this.zb, this.x, this.y, this.parentframe, 1)) { this.x += 1; for (var i = 0; i < this.divs.length; i++) { var left = parseint(this.divs[i].style.left); this.divs[i].style.left = (left + this.parentframe.unit) + "px"; } } } //变形 this.change = function() { //变形的公式 //小div的2个相对坐标点改变 x = y ; y= 3-x; 比如 (0,1) 变化之后 就是 x=1,y=3-0 -> (1,3) //循环4个小div if (!canmove(this.zb, this.x, this.y, this.parentframe, 4)) { if (this.x < 0) { this.x += 1; } else { this.x -= 1; } } for (var i = 0; i < this.divs.length; i++) { //根据公式改变每个div的相对偏移量,2个一改 var temp = this.zb[i * 2] this.zb[i * 2] = this.zb[i * 2 + 1]; this.zb[i * 2 + 1] = 3 - temp; //根据改变后的偏移量计算图形的当前left和top this.divs[i].style.top = ((this.y + parseint(this.zb[i * 2])) * this.parentframe.unit) + "px"; this.divs[i].style.left = ((this.x + parseint(this.zb[i * 2 + 1])) * this.parentframe.unit) + "px"; } } this.movedown = function() { var $this = this =="window" ? this.frame.samlldiv : this; if (canmove($this.zb, $this.x, $this.y, $this.parentframe, 3)) { $this.y += 1; for (var i = 0; i < $this.divs.length; i++) { var top = parseint($this.divs[i].style.top); $this.divs[i].style.top = (top + $this.parentframe.unit) + "px"; } return false; } else { clearinterval($this.parentframe.intervalid); // var temp = $this.parentframe.content.getelementsbytagname("div"); for (var i=0;i<$this.divs.length;i++) { //div变灰 //$this.divs[i].classname ="smalldivblack"; var $y = $this.y + parseint($this.zb[i*2]); var $x = $this.x+parseint($this.zb[i*2+1]); // debugger; $this.parentframe.datas[$y*$this.parentframe.row+ $x] =1; $this.divs[i].dataset.row=$y; //记录div所在的行 $this.divs[i].dataset.col=$x; //记录div所在的列 $this.divs[i].classname="smalldivblack"; $this.divs[i].style.backgroundcolor="black"; //$this.parentframe.datas[] } //消行并计分 for (var i= 0;i<$this.parentframe.col;i++) { //i为行 //判断是否满足消行条件 for (var j=0;j<$this.parentframe.row;j++) { //j为列 if($this.parentframe.datas[i*$this.parentframe.row+ j] !=1){ break; } } //消行,将该行上面的所有div下移一行 if(j==$this.parentframe.row){ var x; //记录div在哪一列 var y; //记录div在哪一行 var getsmalldiv=document.getelementbyid("tfrime").getelementsbyclassname("smalldivblack");//得到小div for (var a=0;a<getsmalldiv.length;a++){ y=parseint(getsmalldiv[a].dataset.row); x=parseint(getsmalldiv[a].dataset.col); if(y==i){ //消除该行 debugger; $this.parentframe.datas[y*$this.parentframe.row+ x]=0; getsmalldiv[a].remove(); a--; } } for (var a=i-1;a>0;a--) { for (var b=0;b<getsmalldiv.length;b++) { y=parseint(getsmalldiv[b].dataset.row); x=parseint(getsmalldiv[b].dataset.col); if(y==a){ //将上面的div下移一行 // debugger; var divtop=parseint(getsmalldiv[b].style.top); getsmalldiv[b].style.top=(divtop+$this.parentframe.unit)+"px"; getsmalldiv[b].dataset.row++; $this.parentframe.datas[y*$this.parentframe.row+ x]=0; $this.parentframe.datas[(y+1)*$this.parentframe.row+ x]=1; } } } $this.line++; // for (var a=0;a<getsmalldiv.length;a++) { // y=parseint(getsmalldiv[a].dataset.row); // x=parseint(getsmalldiv[a].dataset.col); //// alert(getsmalldiv[a].dataset.row); // if(y<i){ //将上面的div下移一行 //// debugger; // var divtop=parseint(getsmalldiv[a].style.top); //// alert(getsmalldiv[a].style.top); // getsmalldiv[a].style.top=(divtop+$this.parentframe.unit)+"px"; // getsmalldiv[a].dataset.row++; // debugger; // $this.parentframe.datas[y*$this.parentframe.row+ x]=0; // $this.parentframe.datas[(y+1)*$this.parentframe.row+ x]=1; // } //// }else if(y==i){ //消除该行 //// debugger; //// $this.parentframe.datas[y*$this.parentframe.row+ x]=0; //// getsmalldiv[a].classname="mainframediv"; //// } // } } } return true; } } // function automovedown() { // // var small = this.frame.samlldiv; // var f = this.frame; // // if (canmove(small.zb, small.x, small.y, 0, f.col, 3)) { // small.y += 1; // for (var i = 0; i < small.divs.length; i++) { // var top = parseint(small.divs[i].style.top); // small.divs[i].style.top = (top + f.unit) + "px"; // } // } else { // clearinterval(f.intervalid); // } // // } //预判能否移动或变化,action:1.右移,2.左移,3.下移,4.变化 //zb是4个小图形的相对偏移,x是图形左偏移,y是top偏移,f是外部frame function canmove(zb, x, y, f, action) { //datas[parseint(zb[i + 1]) + x + 1)+(this.y-1)*row] !=0 switch (action) { case 1: // debugger; for (var i = 0; i < zb.length; i += 2) { if (parseint(zb[i + 1]) + x + 1 >= f.row) { return false; }else if(f.datas[(parseint(zb[i + 1]) + x + 1)+(y+parseint(zb[i]))*f.row] !=0) { return false; } } break; case 2: for (var i = 0; i < zb.length; i += 2) { if (parseint(zb[i + 1]) + x - 1 < 0 ) { return false; }else if(f.datas[(parseint(zb[i + 1]) + x - 1)+(y+parseint(zb[i]))*f.row] !=0) { return false; } } break; case 3: for (var i = 0; i < zb.length; i += 2) { if (parseint(zb[i]) + y + 1 >= f.col || f.datas[(parseint(zb[i + 1]) + x)+(parseint(zb[i]) + y+1)*f.row] !=0) { return false; } } break; case 4: for (var i = 0; i < zb.length; i += 2) { var temp = 3 - zb[i]; if (temp + x < 0 || temp + x >= f.row) { return false; } } break; } return true; } this.rescore=function(){ var gamescore=document.getelementbyid("score"); gamescore.innerhtml=parseint(gamescore.innerhtml)+this.parentframe.score[this.line]; } }
index.js
var frame; function initgame() { frame = new gameframe(16,20,38); frame.init(); document.body.addeventlistener("keydown",moveorchange) } function changespeed(){ frame.changespeed(); } function regame(){ location.reload(); } function moveorchange() { switch(event.keycode) { case 38: //变形(上方向键) frame.change(); break; case 37: //左移动 frame.moveleft(); break; case 39://右移动 frame.moveright(); break; case 40: //向下 frame.movedown(); break; } }
总结
以上所述是小编给大家介绍的使用js代码实现俄罗斯方块游戏,希望对大家有所帮助
上一篇: AI画板中多余的部分怎么快速删除?