前段时间论坛上看到,大牛贴出来的Javascript版俄罗斯方块,实在是佩服之极,恰巧本人也在学习Javascript,所以先看懂了那段代码,然后自己写了一个出来,说真的看懂和能写出来完全是天壤之别,写的时候很多次都实在想不通了,只有回头再看看代码、再想想逻辑,才能接着写下去,最终还是写出来了,不过只是具备基本功能的版本而已,之后准备再出N个版本的方块出来,一步一步完善各种功能,做一个高品质的方块出来。如果大家有什么好的意见,欢迎交流~
本人QQ:605494869 新浪微博:http://weibo.com/605494869,非常欢迎加好友和互粉~
具体代码如下:
- HTML code
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> .c{margin:1px; width:19px; height:19px; background:red; position:absolute;} .d{margin:1px; width:19px; height:19px; background:gray; position:absolute;} .f{top:0px; left:0px; background:black; position:absolute;} </style> <script type="text/javascript"> var row = 18; var col = 10; var size = 20; var isOver = false; var shapes = ("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";"); var tetris; var container; // 创建DIV的公用方法 function createElm(tag,css) { var elm = document.createElement(tag); elm.className = css; document.body.appendChild(elm); return elm; } // 方块类 function Tetris(css,x,y,shape) { // 创建4个div用来组合出各种方块 var myCss = css?css:"c"; this.divs = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)]; this.container = null; this.refresh = function() { this.x = (typeof(x)!='undefined')?x:3; this.y = (typeof(y)!='undefined')?y:0; this.shape = shape?shape:shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(","); if(this.container&&!this.container.check(this.x,this.y,this.shape)) { isOver = true; alert("游戏结束"); } else { this.show(); } } // 显示方块 this.show = function() { for(var i in this.divs) { this.divs[i].style.top = (this.shape[i*2+1]- -this.y)*size+"px"; this.divs[i].style.left = (this.shape[i*2]- -this.x)*size+"px"; } } // 水平移动方块的位置 this.hMove = function(step) { if(this.container.check(this.x- -step,this.y,this.shape)) { this.x += step; this.show(); } } // 垂直移动方块位置 this.vMove = function(step) { if(this.container.check(this.x,this.y- -step,this.shape)) { this.y += step; this.show(); } else { this.container.fixShape(this.x,this.y,this.shape); this.container.findFull(); this.refresh(); } } // 旋转方块 this.rotate = function() { var newShape = [this.shape[1],3-this.shape[0],this.shape[3],3-this.shape[2],this.shape[5],3-this.shape[4],this.shape[7],3-this.shape[6]]; if(this.container.check(this.x,this.y,newShape)) { this.shape = newShape; this.show(); } } this.refresh(); } function Container() { // 设置背景 this.createBackground = function() { var bgDiv = createElm("div","f"); bgDiv.style.width = size*col+"px"; bgDiv.style.height = size*row+"px"; } // 检查边界越界 this.check = function(x,y,shape) { var flag = false; var leftmost=col; var rightmost=0; var undermost=0; for(var i=0;i<8;i+=2) { // 记录最左边水平坐标 if(shape[i]<leftmost) { leftmost = shape[i]; } // 记录最右边水平坐标 if(shape[i]>rightmost) { rightmost = shape[i]; } // 记录最下边垂直坐标 if(shape[i+1]>undermost) { undermost = shape[i+1]; } // 判断是否碰撞 if(this[(shape[i+1]- -y)*100- -(shape[i]- -x)]) { flag = true; } } // 判断是否到达极限高度 for(var m=0;m<3;m++) { for(var n=0;n<col;n++) { if(this[m*100+n]) { flag = true; } } } if((rightmost- -x+1)>col || (leftmost- -x)<0 || (undermost- -y+1)>row || flag) { return false; } return true; } // 用灰色方块替换红色方块,并在容器中记录灰色方块的位置 this.fixShape = function(x,y,shape) { var t = new Tetris("d",x,y,shape); for(var i=0;i<8;i+=2) { this[(shape[i+1]- -y)*100- -(shape[i]- -x)] = t.divs[i/2]; } } // 遍历整个容器,判断是否可以消除 this.findFull = function() { for(var m=0;m<row;m++) { var count = 0; for(var n=0;n<col;n++) { if(this[m*100+n]) { count++; } } if(count==col) { this.removeLine(m); } } } // 消除指定一行方块 this.removeLine = function(row) { // 移除一行方块 for(var n=0;n<col;n++) { document.body.removeChild(this[row*100+n]); } // 把所消除行上面所有的方块下移一行 for(var i=row;i>0;i--) { for(var j=0;j<col;j++) { this[i*100- -j]=this[(i-1)*100- -j] if(this[i*100- -j]) { this[i*100- -j].style.top = i*size + "px"; } } } } } function init() { container = new Container(); container.createBackground(); tetris = new Tetris(); tetris.container = container; document.onkeydown = function(e) { if(isOver) return; var e = window.event?window.event:e; switch(e.keyCode) { case 38: //up tetris.rotate(); break; case 40: //down tetris.vMove(1); break; case 37: //left tetris.hMove(-1); break; case 39: //right tetris.hMove(1); break; } } setInterval("if(!isOver) tetris.vMove(1)",500); } </script> </head> <body onload="init()"> </body> </html>