<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<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; }
.controlModel { margin: 5px; width: 60px; height: 60px; background: #ADD8E6; position: absolute; text-align: center; font-size: 10pt; line-height: 50px; }
.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; }
</style>
<script type="text/javascript">
var tetris;
var container;
var intervalId;
var intervalId2;
var speed = 600;
var size = 20;
var forecastSize = 10;
var controlSize = 65;
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 isFromMobile() {
var flag;
var userAgentInfo = navigator.userAgent;
if (userAgentInfo.indexOf("Windows NT") == -1)
flag = true;
else
flag = false;
return flag;
}
function Tetris(css, x, y, shape) {
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.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;
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 {
this.container.fixShape(this.x, this.y, this.shape);
this.container.findFull();
this.refresh();
clearInterval(intervalId2);
}
}
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";
var anDiv = createElm("div", "info");
anDiv.style.top = forecastSize + "px";
anDiv.style.left = size * colCount - -forecastSize + "px";
if (isFromMobile()) {
var ctShape = [0, 0, 1, 0, 2.5, 0, 3.5, 0];
var ctDiv = [createElm("div", "controlModel", "leftEvent"),
createElm("div", "controlModel", "rightEvent"),
createElm("div", "controlModel", "rotateEvent"),
createElm("div", "controlModel", "quickdownEvent")]
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("leftEvent");
var rightEvent = document.getElementById("rightEvent");
var quickdownEvent = document.getElementById("quickdownEvent");
var rotateEvent = document.getElementById("rotateEvent");
leftEvent.ontouchend = function() { tetris.hMove(-1); };
rightEvent.ontouchend = function() { tetris.hMove(1); };
quickdownEvent.ontouchend = function() { tetris.quickDown(); };
rotateEvent.ontouchend = function() { tetris.rotate(); };
leftEvent.innerHTML = "左";
rightEvent.innerHTML = "右";
quickdownEvent.innerHTML = "瞬落";
rotateEvent.innerHTML = "旋转";
bgDiv.ontouchend = function() { toggleInterval(); };
anDiv.innerHTML = "玩法说明:<br/>瞬落:'空格'<br/>暂停:'点击黑色'<br/>暂停:'点击方块'<br/>旋转:'上方向键'";
} else {
bgDiv.onclick = function() { toggleInterval(); };
anDiv.innerHTML = "玩法说明:<br/>瞬落:'空格'<br/>暂停:'回车'<br/>暂停:'点击方块'<br/>旋转:'上方向键'";
}
anDiv.innerHTML = anDiv.innerHTML + '<br/><br/>作者:stone<br/>微博:<a href="http://weibo.com/605494869">weibo.com/605494869</a>';
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 32:
tetris.quickDown();
break;
case 38:
tetris.rotate();
break;
case 40:
tetris.vMove(1);
break;
case 37:
tetris.hMove(-1);
break;
case 39:
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>