今天加入:1.暂停功能,2.瞬落功能,3.调整预告和计分栏的位置,效果图如下:
本来还想加入等级系统和支持手机的,今天实在木有时间了,下次一定更新上来。
本人QQ:605494869 新浪微博:http://weibo.com/605494869,非常欢迎加好友和互粉~
具体代码如下:
- HTML code
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> .activityModel{margin:1px; width:19px; height:19px; background:red; position:absolute;} .forecastModel{margin:0.5px; width:9.5px; height:9.5px; background:yellow; position:absolute;} .stationaryModel{margin:1px; width:19px; height:19px; background:gray; position:absolute;} .container{top:0px; left:0px; background:black; position:absolute;} .info{top:0px; position:absolute;} .score{width:80px; height:20px; font-size:10pt; text-align:right; color:white; position:absolute;} .forecast{top:0px; left:0px; width:48px; height:48px; background:#151515; position:absolute;} </style> <script type="text/javascript"> var tetris; var container; var intervalId; var intervalId2; var speed = 600; var size = 20; var forecastSize = 10; var rowCount = 18; var colCount = 10; var announcement = 6; var isOver = false; var isStop = 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(";"); 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:"activityModel"; this.divs = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)]; if(!shape) { // 初始化计分栏 this.score = createElm("div","score"); this.score.style.top = "0px"; this.score.style.left = 6*size+"px"; this.score.innerHTML = "score:000"; // 初始化预告栏和预告方块 var forecastCss = "forecastModel"; this.forecast = createElm("div","forecast"); this.divs2 = [createElm("div",forecastCss),createElm("div",forecastCss),createElm("div",forecastCss),createElm("div",forecastCss)]; } this.container = null; this.refresh = function() { this.x = (typeof(x)!='undefined')?x:3; this.y = (typeof(y)!='undefined')?y:0; // 如果有传参,优先使用参数的,如果有预告,优先使用预告,都没有就自己生成 if(shape) this.shape = shape; else if(this.shape2) this.shape = this.shape2; else this.shape = shape?shape:shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(","); this.shape2 = 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.showScore(); this.showAnnouncement(); } } // 显示方块 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.showAnnouncement = function() { for(var i in this.divs2) { this.divs2[i].style.top = (this.shape2[i*2+1]- -0.2)*forecastSize+"px"; this.divs2[i].style.left = (this.shape2[i*2]- -0.2)*forecastSize+"px"; } } // 显示分数 this.showScore = function() { if(this.container && this.score) { switch((this.container.score + "").length) { case 1: this.score.innerHTML = "score:" + "00" + this.container.score; break; case 2: this.score.innerHTML = "score:" + "0" + this.container.score; break; default : this.score.innerHTML = "score:" + this.container.score; break; } } } // 水平移动方块的位置 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(); clearInterval(intervalId2); } } // 旋转方块 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.init = function() { // 绘制方块所在区域 var bgDiv = createElm("div","container"); bgDiv.style.width = size*colCount+"px"; bgDiv.style.height = size*rowCount+"px"; // 绘制预告所在区域 var bgDiv = createElm("div","info"); bgDiv.style.left = size*colCount+"px"; bgDiv.style.width = size*announcement+"px"; bgDiv.style.height = size*rowCount+"px"; bgDiv.innerHTML = " 特殊说明:<br/> 回车:'暂停'<br/> 空格:'瞬落'"; // 清空积分 this.score = 0; } this.check = function(x,y,shape) { // 检查边界越界 var flag = false; var leftmost=colCount; 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<colCount;n++) if(this[m*100+n]) flag = true; if((rightmost- -x+1)>colCount || (leftmost- -x)<0 || (undermost- -y+1)>rowCount || flag) return false; return true; } // 用灰色方块替换红色方块,并在容器中记录灰色方块的位置 this.fixShape = function(x,y,shape) { var t = new Tetris("stationaryModel",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() { var s = 0; for(var m=0;m<rowCount;m++) { var count = 0; for(var n=0;n<colCount;n++) if(this[m*100+n]) count++; if(count==colCount) { s++; this.removeLine(m); } } this.score -= -this.calScore(s); } this.calScore = function(s) { if(s!=0) return s- -this.calScore(s-1) else return 0; } // 消除指定一行方块 this.removeLine = function(rowCount) { // 移除一行方块 for(var n=0;n<colCount;n++) document.body.removeChild(this[rowCount*100+n]); // 把所消除行上面所有的方块下移一行 for(var i=rowCount;i>0;i--) { for(var j=0;j<colCount;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.init(); tetris = new Tetris(); tetris.container = container; document.onkeydown = function(e) { var e = window.event?window.event:e; if(e.keyCode == 13) toggleInterval(); if(isOver || isStop) return; switch(e.keyCode) { case 13: stopInterval(); break; case 32: intervalId2 = setInterval("if(!isOver) tetris.vMove(1)",1); break; 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; } } // 方块开始下降 intervalId = setInterval("if(!isOver) tetris.vMove(1)",speed); } // 控制暂定 function toggleInterval() { if(isStop) { isStop = false; intervalId = setInterval("if(!isOver) tetris.vMove(1)",speed); } else { isStop = true; clearInterval(intervalId); } } </script> </head> <body onload="init()"> </body> </html>