视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用JS代码实现俄罗斯方块游戏
2020-11-27 22:10:35 责编:小采
文档

简单的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代码实现俄罗斯方块游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

下载本文
显示全文
专题