大家好:
昨天参考的俄罗斯方块,适用于PC端,上下左右箭头。今天增进一版手机端可点击按钮进行操作!还不是特别完善,仍需要改进!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>俄罗斯方块-移动版</title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<script type="text/javascript" src="../js/jquery-1.7.2.js"></script>
<!-- css -->
<style type="text/css">
body {
overflow: hidden;
background: #D7D7D7;
}
/* 俄罗斯方块整体样式 */
#tetris {
width: 360px;
border: 1px solid black;
padding: 20px;
align-content: center;
}
/* 俄罗斯方块区域样式-画布样式 */
#canvas {
width: 200px;
height: 400px;
position: relative;
background: -webkit-linear-gradient(top,transparent 19px,blue 20px),-webkit-linear-gradient(left,transparent 19px,red 10px);
background-size: 20px 20px;
background-color: white;
color: #fff;
}
.square {
position: absolute;
width: 17px;
height: 17px;
border: 1px solid white;
}
.type0 { background-color: #A000F0;}
.type1 { background-color: #00F0F0;}
.type2 { background-color: #F0A000;}
.type3 { background-color: #0000F0;}
.type4 { background-color: #00F000;}
.type5 { background-color: #F00000;}
.type6 { background-color: #F0F000;}
/*下一个图标样式*/
#next_shape {
position: relative;
background-color: #000;
border: 1px solid white;
width: 100px;
height: 100px;
}
/*属性样式*/
#info {
background-color: #000;
color: #fff;
float: right;
width: 110px;
height: 380px;
padding: 10px;
}
/*操作按钮样式*/
.buttons>input{
margin: 20px auto;
display: inline-block;
padding: 10px 20px;
color: #fff;
background-color: #45c01a;
border-radius: 5px;
}
</style>
<!-- css ends -->
<!-- script -->
<script type="text/javascript">
$(document).ready(function(){
//开始方法
tetris.init();
if(!Array.prototype.eachdo){
Array.prototype.eachdo = function(fn){
for (var i=0; i < this.length; i++){
fn.call(this[i], i);
}
};
}
if(!Array.prototype.remDup){
Array.prototype.remDup = function(){
var temp = [];
for(var i =0; i < this.length; i++){
var bool = true;
for (var j = i+1; j < this.length; j++){
if(this[i] === this[j]){ bool = false;}
}
if(bool === true){temp.push(this[i]);}
}
return temp;
}
}
});
//画板标准:20行,10列,以正方形为单位
//由4个小正方形组成
//有7种形态:S形,Z形,L形,J形,I形,O形,T形。
var tetris = {
board: [],
boardDiv: null,
canvas: null,
pSize: 20,
canvasHeight: 400,
canvasWidth: 200,
boardHeight: 0,
boardWidth: 0,
spawnX: 4,
spawnY: 1,
shapes: [
[
[-1,1],[0,1],[1,1],[0,0] //TEE
],
[
[-1,0],[0,0],[1,0],[2,0] //line
],
[
[-1,-1],[-1,0],[0,0],[1,0] //L EL
],
[
[1,-1],[-1,0],[0,0],[1,0] //R EL
],
[
[0,-1],[1,-1],[-1,0],[0,0] // R ess
],
[
[-1,-1],[0,-1],[0,0],[1,0] //L ess
],
[
[0,-1],[1,-1],[0,0],[1,0] //square
]
],
tempShapes: null,
curShape: null,
curShapeIndex: null,
curX: 0,
curY: 0,
curSqs: [],
nextShape: null,
nextShapeDisplay: null,
nextShapeIndex: null,
sqs: [],
score: 0,
scoreDisplay: null,
level: 1,
levelDisplay: null,
numLevels: 10,
time: 0,
maxTime: 1000,
timeDisplay: null,
isActive: 0,
curComplete: false,
timer: null,
sTimer: null,
speed: 700,
lines: 0,
//开始方法
init: function() {
this.canvas = document.getElementById("canvas");
this.initBoard();
this.initInfo();
this.initLevelScores();
this.initShapes();
this.buttonEvents();
this.play();
},
initBoard: function() {
this.boardHeight = this.canvasHeight/this.pSize;
this.boardWidth = this.canvasWidth/this.pSize;
var s = this.boardHeight * this.boardWidth;
for (var i=0; i < s; i++) {
this.board.push(0);
}
//this.boardDiv = document.getElementById('board); //for debugging
},
initInfo: function() {
this.nextShapeDisplay = document.getElementById("next_shape");
this.levelDisplay = document.getElementById("level").getElementsByTagName("span")[0];
this.timeDisplay = document.getElementById("time").getElementsByTagName("span")[0];
this.scoreDisplay = document.getElementById("score").getElementsByTagName("span")[0];
this.linesDisplay = document.getElementById("lines").getElementsByTagName("span")[0];
this.setInfo('time');
this.setInfo('score');
this.setInfo('level');
this.setInfo('lines');
},
initShapes: function() {
this.curSqs = [];
this.curComplete = false;
this.shiftTempShapes();
this.curShapeIndex = this.tempShapes[0];
this.curShape = this.shapes[this.curShapeIndex];
this.initNextShape();
this.setCurCoords(this.spawnX, this.spawnY);
this.drawShape(this.curX, this.curY, this.curShape);
},
initNextShape: function() {
if(typeof this.tempShapes[1] === 'undefined') {this.initTempShapes();}
try {
this.nextShapeIndex = this.tempShapes[1];
this.nextShape = this.shapes[this.nextShapeIndex];
this.drawNextShape();
} catch(e) {
throw new Error("Could not create next shape. " + e);
}
},
initTempShapes: function(){
this.tempShapes = [];
for (var i =0; i < this.shapes.length; i++){
this.tempShapes.push(i);
}
var k = this.tempShapes.length;
while ( --k ){ //Fisher Yates Shuffle
var j = Math.floor(Math.random()*(k + 1));
var tempk = this.tempShapes[k];
var tempj = this.tempShapes[j];
this.tempShapes[k] = tempj;
this.tempShapes[j] = tempk;
}
},
shiftTempShapes: function(){
try {
if (typeof this.tempShapes === "undefined" || this.tempShapes === null) {
this.initTempShapes();
} else {
this.tempShapes.shift();
}
} catch (e) {
throw new Error("Could not shift or init tempShapes: " +e);
}
},
initTimer: function(){
var me = this;
var tLoop = function(){
me.incTime();
me.timer = setTimeout(tLoop, 2000);
};
this.timer = setTimeout(tLoop, 2000);
},
initLevelScores: function(){
var c = 1;
for (var i = 1; i <= this.numLevels; i++){
this['level' + i] = [c * 1000, 40 * i, 5 * i]; //for nxt level, row score, p sore,
c = c + c;
}
},
setInfo: function(el){
this[el + 'Display'].innerHTML = this[el];
},
drawNextShape: function(){
var ns = [];
for (var i = 0; i < this.nextShape.length; i++){
ns[i] = this.createSquare(this.nextShape[i][0] + 2, this.nextShape[i][1] + 2, this.nextShapeIndex);
}
this.nextShapeDisplay.innerHTML = '';
for (var k = 0; k < ns.length; k++){
this.nextShapeDisplay.appendChild(ns[k]);
}
},
drawShape: function(x, y, p){
for (var i = 0; i < p.length; i++){
var newX = p[i][0] + x;
var newY = p[i][1] + y;
this.curSqs[i] = this.createSquare(newX, newY, this.curShapeIndex);
}
for (var k = 0; k < this.curSqs.length; k++){
this.canvas.appendChild(this.curSqs[k]);
}
},
createSquare: function(x, y, type){
var el = document.createElement('div');
el.className = 'square type' +type;
el.style.left = x * this.pSize + 'px';
el.style.top = y * this.pSize + 'px';
return el;
},
removeCur: function(){
var me = this;
this.curSqs.eachdo(function(){
me.canvas.removeChild(this);
});
this.curSqs = [];
},
setCurCoords: function(x, y){
this.curX = x;
this.curY = y;
},
//获取按钮点击事件
buttonEvents: function(){
var me = this;
//判断哪个按钮点击了
buttonOnclick();
//判断点击按钮的值
var cb = function(){
me.buttonKey();
};
},
//获取按钮点击的值
buttonKey: function(){
var button_value = $("#button_value").val();
switch(button_value){
case 37://左移
this.move('L');
break;
case 38://旋转变形
this.move('RT');
break;
case 39://右移
this.move('R');
break;
case 40://向下
this.move('D');
break;
default:
break;
}
},
incTime: function(){
this.time++;
this.setInfo('time');
},
incScore: function(amount){
this.score = this.score + amount;
this.setInfo('score');
},
incLevel: function(){
this.level++;
this.speed = this.speed - 75;
this.setInfo('level');
},
incLines: function(num){
this.lines += num;
this.setInfo('lines');
},
calcScore: function(args){
var lines = args.lines || 0;
var shape = args.shape || false;
var speed = args.speed || 0;
var score = 0;
if (lines > 0) {
score += lines * this["level" + this.level][1];
this.incLines(lines);
}
if (shape === true) {score += shape * this["level" + this.level][2];}
/*if (speed > 0){ score += speed * this["level" +this .level[3]];}*/
this.incScore(score);
},
checkScore: function(){
if (this.score >= this["level" + this.level][0]){
this.incLevel();
}
},
gameOver: function(){
this.clearTimers();
this.rebuttons.innerHTML = "<h1>游戏结束!</h1>";
},
play: function(){
var me = this;
if (this.timer === null){
this.initTimer();
}
var gameLoop = function(){
me.move('D');
if(me.curComplete){
me.markBoardShape(me.curX, me.curY, me.curShape);
me.curSqs.eachdo(function(){
me.sqs.push(this);
});
me.calcScore({shape: true});
me.checkRows();
me.checkScore();
me.initShapes();
me.play();
} else {
me.pTimer = setTimeout(gameLoop, me.speed);
}
};
this.pTimer = setTimeout(gameLoop, me.speed);
this.isActive = 1;
},
togglePause: function(){
if (this.isActive === 1){
this.clearTimers();
this.isActive = 0;
}else {this.play();}
},
clearTimers: function(){
clearTimeout(this.timer);
clearTimeout(this.pTimer);
this.timer = null;
this.pTimer = null;
},
move: function(dir){
var s = '';
var me = this;
var tempX = this.curX;
var tempY = this.curY;
switch(dir){
case 'L':
s = 'left';
tempX -= 1;
break;
case 'R':
s = 'left';
tempX += 1;
break;
case 'D':
s = 'top';
tempY += 1;
break;
case 'RT':
this.rotate();
return true;
break;
default:
throw new Error('wtf');
break;
}
//检查是否移动
if (this.checkMove(tempX, tempY, this.curShape)){
this.curSqs.eachdo(function(i) {
var l = parseInt(this.style[s], 10);
dir === 'L' ? l -= me.pSize : l += me.pSize;
this.style[s] = l + 'px';
});
this.curX = tempX;
this.curY = tempY;
} else if (dir === 'D') {
if (this.curY === 1 || this.time === this.maxTime) {
this.gameOver();
return false;
}
this.curComplete = true;
}
},
rotate: function(){
if (this.curShapeIndex !== 6) { //square
var temp = [];
this.curShape.eachdo(function(){
temp.push([this[1] * -1, this[0]]);
});
if (this.checkMove(this.curX, this.curY, temp)) {
this.curShape = temp;
this.removeCur();
this.drawShape(this.curX, this.curY, this.curShape);
} else {
throw new Error ("Could not rotate!");
}
}
},
checkMove: function(x, y, p){
if (this.isOB(x, y, p) ||
this.isCollision(x, y, p)) {
return false;
}
return true;
},
isCollision: function(x, y, p) {
var me = this;
var bool = false;
p.eachdo(function(){
var newX = this[0] + x;
var newY = this[1] + y;
if (me.boardPos(newX, newY) === 1) {
bool = true;
}
});
return bool;
},
isOB: function(x, y, p){
var w = this.boardWidth - 1;
var h = this.boardHeight -1;
var bool = false;
p.eachdo(function(){
var newX = this[0] + x;
var newY = this[1] + y;
if(newX < 0 || newX > w || newY < 0 || newY > h){
bool = true;
}
});
return bool;
},
getRowState: function(y){
var c = 0;
for (var x = 0; x < this.boardWidth; x++){
if (this.boardPos(x, y) === 1){
c = c + 1;
}
}
if (c === 0){
return 'E';}
if (c === this.boardWidth) { return 'F'; }
return 'U';
},
checkRows: function(){
var me = this;
var start = this.boardHeight;
this.curShape.eachdo(function(){
var n = this[1] + me.curY;
console.log(n);
if (n < start) {
start = n;
}
});
console.log(start);
var c = 0;
var stopCheck = false;
for (var y= this.boardHeight - 1; y >=0; y--){
switch(this.getRowState(y)){
case 'F':
this.removeRow(y);
c++;
break;
case 'E':
if (c === 0){
stopCheck = true;
}
break;
case 'U':
if (c > 0){
this.shiftRow(y, c);
}
break;
default:
break;
}
if (stopCheck === true){
break;
}
}
if (c > 0){
this.calcScore({ lines: c});
}
},
shiftRow: function(y, amount){
var me = this;
for (var x = 0; x < this.boardWidth; x++){
this.sqs.eachdo(function(){
if (me.isAt(x, y, this)){
me.setBlock(x, y + amount, this);
}
});
}
me.emptyBoardRow(y);
},
emptyBoardRow: function(y){
for (var x = 0; x < this.boardWidth; x++){
this.markBoardAt(x, y, 0);
}
},
removeRow: function(y){
for (var x =0; x < this.boardWidth; x++){
this.removeBlock(x, y);
}
},
removeBlock: function(x, y){
var me = this;
this.markBoardAt(x, y, 0);
this.sqs.eachdo(function(i){
if (me.getPos(this)[0] === x && me.getPos(this)[1] === y){
me.canvas.removeChild(this);
me.sqs.splice(i, 1);
}
});
},
setBlock: function(x, y, block){
this.markBoardAt(x, y, 1);
var newX = x * this.pSize;
var newY = y * this.pSize;
block.style.left = newX + 'px';
block.style.top = newY + "px";
},
isAt: function(x, y, block){
if(this.getPos(block)[0] === x && this.getPos(block)[1] === y){
return true;
}
return false;
},
getPos: function(block){
var p = [];
p.push(parseInt(block.style.left, 10)/ this.pSize);
p.push(parseInt(block.style.top, 10)/ this.pSize);
return p;
},
getBoardIdx: function(x, y){
return x + (y * this.boardWidth);
},
boardPos: function(x, y){
return this.board[x + (y * this.boardWidth)];
},
markBoardAt: function(x, y, val){
this.board[this.getBoardIdx(x, y)] = val;
},
markBoardShape: function(x, y, p){
var me = this;
p.eachdo(function(i){
var newX = p[i][0] + x;
var newY = p[i][1] + y;
me.markBoardAt(newX, newY, 1);
});
},
isIE: function(){
return this.bTest(/IE/);
},
isFirefox: function(){
return this.bTest(/Firefox/);
},
isSafari: function(){
return this.bTest(/Safari/);
},
bTest: function(rgx){
return rgx.test(navigator.userAgent);
}
};
//按钮点击事件
function buttonOnclick(){
//点击事件-左移
$("#moveleft").click(function(){
$("#button_value").val(37);
tetris.move('L');
});
//点击事件-旋转变形
$("#deformation").click(function(){
$("#button_value").val(38);
tetris.move('RT');
});
//点击事件-右移
$("#moveright").click(function(){
$("#button_value").val(39);
tetris.move('R');
});
//点击事件-向下
$("#movedown").click(function(){
$("#button_value").val(40);
tetris.move('D');
});
}
//重新开始
function reagen(){
//重新加载当前文档
location.reload();
}
</script>
<!-- script end-->
</head>
<body>
<div align="left" >
<a href="javascript:;" onClick="javascript:history.back(-1);">
<img height="50" width="50" src="../img/tubiao/1.png" border="0" title="返回上一页" >
</a>
</div>
<div style="text-align:center;clear:both;">
<div id="tetris">
<div id="rebuttons" class="buttons" align="center" style="max-width: 100; height: auto;">
<input type="button" id="reagen" value="重新开始" style="background-color: #F0A000;" onclick="reagen()"/>
</div>
<div id="info">
<div id="next_shape">下一个图标</div>
<p id="level">速度: <span></span></p>
<p id="lines">行数: <span></span></p>
<p id="score">得分: <span></span></p>
<p id="time">计时: <span></span></p>
</div>
<!--俄罗斯方块 -->
<div id="canvas">
--> </div>
<!--操作按钮-->
<!--隐藏值:0 无操作;1:左移;2:右移;3:下降;4:旋转-->
<input type="hidden" id="button_value" value="0" />
<div id="buttons" class="buttons" align="center" style="max-width: 100; height: auto;">
<input type="button" id="moveleft" value="左移" />
<input type="button" id="moveright" value="右移" />
<input type="button" id="movedown" value="下降" />
<input type="button" id="deformation" value="旋转"/>
</div>
</div>
</div>
</body>
</html>