分享自己写的Javascript的俄罗斯方块+送分(四)
加入按钮支持触屏手机操作,但是遇到一个问题,为神马手机上点按钮反应会那么慢呢???这样完全不能正常游戏嘛,求高人解释一下~~谢谢啦~
<!DOCTYPE html><html><head><title></title><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"><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;} .controlModel{margin:5px; width:50px; height:50px; background:#ADD8E6; position:absolute; text-align:center; font-size:10pt } .container{top:0px; left:0px; background:black; position:absolute;} .info{top:0px; position:absolute; font-size:10pt; word-break:break-all;} .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 controlSize = 55;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,id){ var elm = document.createElement(tag); elm.className = css; if(id) elm.id = id; 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 c = "forecastModel"; this.forecast = createElm("div","forecast"); this.divs2 = [createElm("div",c),createElm("div",c),createElm("div",c),createElm("div",c)]; } 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; var c = confirm("重新开始?"); if(c) location.reload(); } 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(isOver || isStop) return; if(this.container.check(this.x- -step,this.y,this.shape)) { this.x += step; this.show(); } } // 垂直移动方块位置 this.vMove = function(step) { if(isOver || isStop) return; if(this.container.check(this.x,this.y- -step,this.shape)) { this.y += step; this.show(); } else { clearInterval(intervalId2); this.container.fixShape(this.x,this.y,this.shape); this.container.findFull(); this.refresh(); } } this.quickDown = function(){ if(isOver || isStop) return; intervalId2 = setInterval("tetris.vMove(1)",1); } // 旋转方块 this.rotate = function() { if(isOver || isStop) return; 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"; bgDiv.onclick = function(){toggleInterval();}; // 绘制预告所在区域 var anDiv = createElm("div","info"); anDiv.style.top = forecastSize+"px"; anDiv.style.left = size*colCount- -forecastSize+"px"; anDiv.innerHTML = "玩法说明:<br/>瞬落:'空格'<br/>暂停:'回车'<br/>暂停:'点击方块'<br/>旋转:'上方向键'" + '<br/><br/>作者:stone<br/><a href="http://weibo.com/605494869">weibo.com/605494869</a>'; // 绘制控制器所在区域 var ctShape = [0,0,1,0,3,0,4,0]; var ctDiv = [createElm("div","controlModel","l"), createElm("div","controlModel","r"), createElm("div","controlModel","ro"), createElm("div","controlModel","q")] for(var i in ctDiv) { ctDiv[i].style.top = (ctShape[i*2+1])*controlSize- -forecastSize- -rowCount*size + "px"; ctDiv[i].style.left = (ctShape[i*2])*controlSize- -forecastSize + "px"; } // 绑定按钮事件和文字 var leftEvent = document.getElementById("l"); var rightEvent = document.getElementById("r"); var quickdownEvent = document.getElementById("d"); var rotateEvent = document.getElementById("ro"); l.onclick = function(){tetris.hMove(-1);}; r.onclick = function(){tetris.hMove(1);}; q.onclick = function(){tetris.quickDown();}; ro.onclick = function(){tetris.rotate();}; l.innerHTML = "左"; r.innerHTML = "右"; q.innerHTML = "瞬落"; ro.innerHTML = "旋转"; // 清空积分 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) { this.removeLine(m); s++; } } 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 32: // quickDown tetris.quickDown();break; case 38: //rotate 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>