上班偷懒写了个JS版的俄罗斯方块,给各位屌丝娱乐娱乐!BUG是有的,也还有很多可以改进的。以后有时间了再整有完美版的,
写这个DEMO主要原因是为了重温下:那些年学习程序开发时,写过的游戏DEMO。
重新拾起当年为"为激情(兴趣)而CODE",而不是现在的为生活而CODE。工作的几年中,总是想方涉法的想在工作中学到更多关于软件开发方面的东西,总是期待在工作中能接触到更多新潮的、前卫的、牛B的技术。要说为什么会这样,原因其实很简单:就是为了在自己在下一份工作中,不落后别人,期待自己掌握的技术越多,找下一份工作就越容易,当然薪水也会涨得相对高点。然后就足渐的迷失了自己当年的那份激情。
看来得找个时间,找个幽静的地方,一个人坐下来好好的思考一下今后的路和方向该怎么走了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
(function () {
var box = {
status: [
//------------------------------------------------------------------------------------------------
/****/
//------------------------------------------------------------------------------------------------
[ //长条****
[
[0, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]
],
[
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]
],
[
[0, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]
],
[
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
*
* */
//------------------------------------------------------------------------------------------------
[
[
[0, 0, 0, 0],
[0, 2, 0, 0],
[0, 2, 2, 2],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 2, 2, 0],
[0, 2, 0, 0],
[0, 2, 0, 0]
],
[
[0, 0, 0, 0],
[2, 2, 2, 0],
[0, 0, 2, 0],
[0, 0, 0, 0]
],
[
[0, 0, 2, 0],
[0, 0, 2, 0],
[0, 2, 2, 0],
[0, 0, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
*
* */
//------------------------------------------------------------------------------------------------
[
[
[0, 0, 0, 0],
[0, 3, 3, 3],
[0, 3, 0, 0],
[0, 0, 0, 0]
],
[
[0, 3, 3, 0],
[0, 0, 3, 0],
[0, 0, 3, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 0, 3, 0],
[3, 3, 3, 0],
[0, 0, 0, 0]
],
[
[0, 3, 0, 0],
[0, 3, 0, 0],
[0, 3, 3, 0],
[0, 0, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
* *
*/
//------------------------------------------------------------------------------------------------
[
[
[0, 4, 0, 0],
[0, 4, 4, 0],
[0, 0, 4, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 4, 4, 0],
[4, 4, 0, 0],
[0, 0, 0, 0]
],
[
[0, 4, 0, 0],
[0, 4, 4, 0],
[0, 0, 4, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 4, 4, 0],
[4, 4, 0, 0],
[0, 0, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
* *
*/
//------------------------------------------------------------------------------------------------
[
[
[0, 0, 5, 0],
[0, 5, 5, 0],
[0, 5, 0, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[5, 5, 0, 0],
[0, 5, 5, 0],
[0, 0, 0, 0]
],
[
[0, 0, 5, 0],
[0, 5, 5, 0],
[0, 5, 0, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[5, 5, 0, 0],
[0, 5, 5, 0],
[0, 0, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
* * */
//------------------------------------------------------------------------------------------------
[
[
[0, 0, 0, 0],
[0, 6, 0, 0],
[6, 6, 6, 0],
[0, 0, 0, 0]
],
[
[0, 6, 0, 0],
[0, 6, 6, 0],
[0, 6, 0, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[6, 6, 6, 0],
[0, 6, 0, 0],
[0, 0, 0, 0]
],
[
[0, 6, 0, 0],
[6, 6, 0, 0],
[0, 6, 0, 0],
[0, 0, 0, 0]
]
] ,
//------------------------------------------------------------------------------------------------
/*
* * */
//------------------------------------------------------------------------------------------------
[
[
[0, 0, 0, 0],
[0, 7, 7, 0],
[0, 7, 7, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 7, 7, 0],
[0, 7, 7, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 7, 7, 0],
[0, 7, 7, 0],
[0, 0, 0, 0]
],
[
[0, 0, 0, 0],
[0, 7, 7, 0],
[0, 7, 7, 0],
[0, 0, 0, 0]
]
]
],
statusSum: 7,
width: 10,
nextStatus: null,
nextIndex: 0,
nextBlock: null,
curIndex: 0,
curStatus: [],
curBlock: null,
color: ["", "red", "green", "blue", "yellow", "orange", "pink", "purple", "black"],
x: 0,
y: 0,
tetris: null,
move: function (x, y) {
this._move(x, y);
this.draw();
},
around: function () {
this.curIndex++;
if (this.curIndex >= 4) {
this.curIndex = 0;
}
this._createBlock(this.curStatus);
var bak = this.curBlock;
this.curBlock = this._createBlock(this.curStatus);
bak.parentNode.removeChild(bak);
},
newBlock: function () {
if (this.curBlock) {
this.curBlock.parentNode.removeChild(this.curBlock);
}
if (this.nextStatus) {
this.curIndex = this.nextIndex;
this.curStatus = this.nextStatus;
this.curBlock = this.nextBlock;
} else {
var statusIndex = Math.random() * 7;
this.curStatus = this.status[parseInt(statusIndex) ];
this.curBlock = this._createBlock(this.curStatus);
}
this.x = 5;
this.y = -4;
this._newNextBlock();
},
_newNextBlock: function () {
var statusIndex = Math.random() * 7;
this.nextStatus = this.status[parseInt(statusIndex) ];
this.nextBlock = this._createBlock(this.nextStatus);
this.drawNext();
},
_move: function (px, py) {
this.x = this.x + px;
this.y = this.y + py;
},
draw: function () {
this.curBlock.style.left = this.x * this.width + "px";
this.curBlock.style.top = this.y * this.width + "px";
},
drawNext: function () {
this.nextBlock.style.left = parseFloat(this.tetris.scoreBox.style.left)+ this.width + "px";
this.nextBlock.style.top = parseFloat(this.tetris.scoreBox.style.top) + 50 + "px";
document.body.appendChild(this.nextBlock)
},
_createBlock: function (_curStatus) {
var bbox = document.createElement("div");
bbox.style.position = "absolute";
var curStatu = _curStatus[this.curIndex];
for (var y in curStatu) {
for (var x in curStatu[y]) {
if (curStatu[y][x] == 0) {
continue;
}
var box = document.createElement("div");
box.style.position = "absolute";
box.style.top = y * this.width + "px";
box.style.left = x * this.width + "px";
box.style.width = this.width + "px";
box.style.height = this.width + "px";
box.style.backgroundColor = this.color[curStatu[y][x]];
bbox.appendChild(box);
}
}
return bbox;
}
};
function Tetris() {
return this.init();
}
Tetris.prototype = {
wall: [],
wallBlocks: [],
wallBox: [],
width: 20,
time: 0,
delay: 500,
isMove: false,
score: 0,
scoreBox: null,
colorBlack: box.color.length - 1,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWM: 40,
init: function () {
this._initWall();
this._createScoreBox();
box.tetris = this;
this.start();
},
_initWall: function () {
for (var y = 0; y < this.width; y++) {
this.wall[y] = [];
for (var x = 0; x < this.width; x++) {
this.wall[y][x] = 0;
if (y == 0 || y == this.width - 1) {
this.wall[y][x] = this.colorBlack;
}
if (x == 0 || x == this.width - 1) {
this.wall[y][x] = this.colorBlack;
}
}
}
this._createWall();
this._paintWall();
},
start: function () {
this._newBox();
document.onkeydown = applyFn(this, this._keypress);
this.time = setInterval(applyFn(this, this._thread), this.delay);
},
_thread: function () {
if (this._canMove(0, 1) && this.isMove) {
box.move(0, 1);
} else {
this.isMove = false;
if (this._isOver()) {
clearInterval(this.time);
this.scoreBox.innerHTML = "<br/>game over!";
} else {
this._copyBoxToWall();
this._deleteLine();//消除行
this._paintWall();
this._newBox();
if (this.score % 2 == 0) {
this.delay = this.delay - this.score * this.score;
}
this.scoreBox.innerHTML = this.score;
}
this.isMove = true;
}
},
_keypress: function (event) {
this.isMove = false;
event = fixEvent(event || window.event);
event.preventDefault();
var x = 0, y = 0;
if (event.which == this.LEFT) {
x = -1, y = 0;
} else if (event.which == this.UP) {
if (this._canRound()) {
box.around();
box.draw();
this.wallBox.appendChild(box.curBlock);
}
}
else if (event.which == this.RIGHT) {
x = 1, y = 0;
}
else if (event.which == this.DOWM) {
x = 0, y = 1;
}
if (this._canMove(x, y) && event.which != this.UP) {
box.move(x, y);
}
this.isMove = true;
},
_newBox: function () {
box.newBlock();
box.draw();
this.isMove = true;
this.wallBox.appendChild(box.curBlock);
},
_canMove: function (px, py) {
var curBox = box.curStatus[box.curIndex];
for (var y = curBox.length - 1; y >= 0; y--) {
for (var x = 0; x < curBox[y].length; x++) {
var wx = (box.x + x + px), wy = (box.y + y + py);
if (px != 0) {
if (wx <= 0) wx = 0;
if (wx >= this.width - 1) wx = this.width - 1;
if (curBox[y][x] > 0 && wy < 0) return false;
if (curBox[y][x] > 0 && this.wall[wy][wx] > 0) return false;
continue;
}
if (py != 0) {
if (wy <= 0) wy = 1;
if (wy >= this.width - 1) wy = this.width - 1;
if (curBox[y][x] > 0 && wy >= this.width - 1) return false;
if (curBox[y][x] > 0 && this.wall[wy][wx] > 0) return false;
}
}
}
return true;
},
_canRound: function () {
var nextIndex = box.curIndex + 1;
if (nextIndex >= 4) nextIndex = 0
var nextBox = box.curStatus[nextIndex];
for (var y = 0; y < nextBox.length; y++) {
for (var x = 0; x < nextBox[y].length; x++) {
var wx = (box.x + x), wy = (box.y + y);
if (nextBox[y][x] > 0 && this.wall[wy] && this.wall[wy][wx] != 0) {
return false;
}
}
}
return true;
},
_isOver: function () {
var curBox = box.curStatus[box.curIndex];
return box.y <= 0
},
_copyBoxToWall: function () {
var curBox = box.curStatus[box.curIndex];
for (var y = 0; y < curBox.length; y++) {
for (var x = 0; x < curBox[y].length; x++) {
var wx = box.x + x;
var wy = box.y + y;
if (wy <= 0) break;
if (curBox[y][x] > 0 && this.wall[wy][wx] == 0) {
this.wall[wy][wx] = curBox[y][x]
}
}
}
},
_deleteLine: function () {
//从边框内开始循环,所有减2
var delLine = [];
var endLine = -1;
var isDel = true;
for (var y = this.width - 2; y > 0; y--) {
isDel = true;
applyFn(this, calCol)(y);
if (endLine != -1) { //>endLine以上行才有方块
break;
}
else if (isDel) { //收集消除行
delLine.push(y);
}
}
if (endLine != -1) {
while (delLine.length) {
this.score++;
for (var y = delLine.pop(); y >= endLine; y--) {
for (var x = 1; x < this.width - 1; x++) {
if (y - 1 <= 0) {
this.wall[y][x] = 0;
}
else {
this.wall[y][x] = this.wall[y - 1][x];
}
}
}
}
}
function calCol(y) {
var sum = this.width - 1;
var count = 1;
for (var x = 1; x < this.width - 1; x++) {
if (this.wall[y][x] == 0) {
isDel = false;
count++;
}
}
if (count == sum) { //>y以上行才有方块
endLine = y;
}
}
},
_createWall: function () {
var wall = document.createElement("div");
wall.style.position = "absolute";
wall.style.overflow = "hidden";
wall.style.width = 20 * box.width + "px";
wall.style.height = 20 * box.width + "px";
wall.style.top = 100 + "px";
wall.style.left = 100 + "px";
document.getElementsByTagName("body")[0].appendChild(wall);
this.wallBox = wall;
for (var y = 0; y < this.width; y++) {
var wallBlockX = [];
for (var x = 0; x < this.width; x++) {
var wallBlock = document.createElement("div");
wallBlock.style.position = "absolute";
wallBlock.style.backgroundColor = box.color[this.wall[y][x]];
wallBlock.style.width = box.width + "px";
wallBlock.style.height = box.width + "px";
wallBlock.style.left = x * box.width + "px";
wallBlock.style.top = y * box.width + "px";
this.wallBox.appendChild(wallBlock);
wallBlockX.push(wallBlock)
}
this.wallBlocks.push(wallBlockX);
}
},
_paintWall: function () {
for (var y = 0; y < this.width; y++) {
var wallBlockXs = this.wallBlocks[y];
for (var x = 0; x < this.width; x++) {
wallBlockXs[x].style.backgroundColor = box.color[this.wall[y][x]];
}
}
},
_createScoreBox: function () {
var scoreBox = document.createElement("div");
scoreBox.style.position = "absolute";
scoreBox.style.border = "1px solid black";
scoreBox.style.overflow = "hidden";
scoreBox.style.width = 100 + "px";
scoreBox.style.height = 100 + "px";
scoreBox.style.top = this.wallBox.style.top;
scoreBox.style.left = 110 + parseFloat(this.wallBox.style.width) + "px";
document.getElementsByTagName("body")[0].appendChild(scoreBox);
this.scoreBox = scoreBox;
}
}
function applyFn(obj, fn) {
return function () {
fn.apply(obj, arguments);
}
}
function callFn(obj, fn) {
return function () {
fn.apply(obj);
}
}
function fixEvent(event) {
if (event.preventDefault) event.preventDefault();
else {
event.preventDefault = function () {
event.returnValue = false;
};
}
if (event.which == null && (event.charCode != null || event.keyCode != null)) {
event.which = event.charCode != null ? event.charCode : event.keyCode;
}
return event;
}
window.Tetris = Tetris;
})();
new Tetris();
</script>
</html>