Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>俄罗斯方块</title>
<script language="javascript" type="text/javascript">
var Sys = null;
function sys()
{
}
sys.prototype = {
GameMap: [],
BlocksMap: [],
SmallMap: [],
BlocksObj: [],
Timer: null,
HorizontalNum: 10,
VerticalNum: 18,
IsBegin: false,
IsMoving: false,
IsGameOver: false,
ScoreStrategy: [100, 300, 500, 800],
LevelScores: [5000, 20000, 40000, 60000, 80000, 100000, 120000, 140000, 160000, 200000],
TotalScore: 0,
IsInAddScore: false,
IsKeyDown: false,
IsPlay: false,
IsFirstPlay: true,
SmallGridNum: 6,
DirectionEnum: { left: 0, right: 1, up: 2, down: 3 },
Speeds: [1000, 900, 800, 700, 600, 500, 400, 300, 200, 100],
CurrentSpeed: 1000,
TypeEnum: { none: 0, block: 1, blocks: 2 },
BlocksEnum: [0, 1, 2, 3, 4, 5, 6,7,8,9], //0为LL,1为LR,2为T,3为ZL,4为ZR,5为I,6为F,7为长T
BlocksNum: [4, 4, 3, 3, 3, 4, 2,5,5,5],
BlocksStateNum: [4, 4, 4, 2, 2, 2, 1,4,4,2],
BlocksShapeMaps: [],
ColorEnum: [[0, 0], [-28, 0], [-56, 0], [-84, 0], [-112, 0], [-140, 0], [-168, 0],[0, 0], [-28, 0], [-56, 0]],
CreateGameMap: function() {
for (var i = 0; i < this.VerticalNum; i++) {
this.GameMap.push([]);
for (var j = 0; j < this.HorizontalNum; j++) {
this.GameMap[i][j] = {};
this.GameMap[i][j][Sys.TypeEnum.blocks] = null;
}
}
},
CreateBlocksShapeMaps: function() {
for (var i = 0; i < this.BlocksEnum.length; i++) {
this._createBlocksShapeMap(i);
}
},
_createBlocksShapeMap: function(index) {
var blocksPoses = [];
switch (index) {
case 0:
var blocksPos1 = [[[2,1]],[[0,2],[1,2],[2,2]]];
var blocksPos2 = [[[1,0]],[[1,1]],[[1,2],[2,2]]];
var blocksPos3 = [[[0,1],[1,1],[2,1]],[[0,2]]];
var blocksPos4 = [[[1,0],[2,0]],[[2,1]],[[2,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 1:
var blocksPos1 = [[[2, 0]], [[2, 1]], [[1, 2], [2, 2]]];
var blocksPos2 = [[[0, 1]], [[0, 2], [1, 2]], [[2, 2]]];
var blocksPos3 = [[[0, 0], [1, 0]], [[0, 1]], [[0, 2]]];
var blocksPos4 = [[[0, 1], [1, 1], [2, 1]], [[2, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 2:
var blocksPos1 = [[[0, 0], [1, 0], [2, 0]], [[1, 1]]];
var blocksPos2 = [[[1, 0]], [[0, 1], [1, 1]], [[1, 2]]];
var blocksPos3 = [[[1, 1]], [[0, 2], [1, 2], [2, 2]]];
var blocksPos4 = [[[0, 0]], [[0, 1], [1, 1]], [[0, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 3:
var blocksPos1 = [[[0, 0]], [[0, 1], [1, 1]], [[1, 2]]];
var blocksPos2 = [[[1, 1], [2, 1]], [[0, 2], [1, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 4:
var blocksPos1 = [[[1, 0]], [[0, 1], [1, 1]], [[0, 2]]];
var blocksPos2 = [[[0, 1], [1, 1]], [[1, 2], [2, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 5:
var blocksPos1 = [[[0, 0]], [[0, 1]], [[0, 2]], [[0, 3]]];
var blocksPos2 = [[[0, 3]], [[1, 3]], [[2, 3]], [[3, 3]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 6:
var blocksPos = [[[0, 0], [0, 1]], [[1, 0], [1, 1]]];
blocksPoses.push(blocksPos);
break;
case 7:
var blocksPos1 = [[[0,0],[1,0],[2,0]],[[1,1]],[[1,2]]];
var blocksPos2 = [[[2,0]],[[0,1],[1,1],[2,1]],[[2,2]]];
var blocksPos3 = [[[1,0]],[[1,1]],[[0,2],[1,2],[2,2]]];
var blocksPos4 = [[[0,0]],[[0,1],[1,1],[2,1]],[[0,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 8:
var blocksPos1 = [[[0,1],[1,1],[2,1]],[[0,2]],[[2,2]]];
var blocksPos2 = [[[1,0],[2,0]],[[2,1]],[[1,2],[2,2]]];
var blocksPos3 = [[[0,1],[2,1]],[[0,2],[1,2],[2,2]]];
var blocksPos4 = [[[1,0],[2,0]],[[1,1]],[[1,2],[2,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 9:
var blocksPos1 = [[[0,0],[1,0]],[[1,1]],[[1,2],[2,2]]];
var blocksPos2 = [[[2,0]],[[0,1],[1,1],[2,1]],[[0,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
}
Sys.BlocksShapeMaps.push(blocksPoses);
},
GetInactivateBlocks: function() {
for (var i = 0; i < Sys.BlocksObj.length; i++) {
if (!Sys.BlocksObj[i].isInGameMap) {
return Sys.BlocksObj[i];
}
}
return null;
},
GetActiviteBlocks: function() {
for (var i = 0; i < this.BlocksObj.length; i++) {
if (this.BlocksObj[i].isInGameMap) {
return this.BlocksObj[i];
}
}
return null;
},
AllowBlocksMove: function(isDown) {
var blocksItem = this.GetActiviteBlocks();
var itemPosArray = this._getBlocksItemPosArray(blocksItem);
var allowDown = true;
if (isDown) {
allowDown = this._allowBlocksDown(itemPosArray, blocksItem, isDown);
}
else {
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var maxItemPosX = itemPosArray.ItemPosXArray[itemPosArray.ItemPosXArray.length - 1];
var minItemPosX = itemPosArray.ItemPosXArray[0];
var maxItemPosY = itemPosArray.ItemPosYArray[itemPosArray.ItemPosYArray.length - 1];
var minItemPosY = itemPosArray.ItemPosYArray[0];
switch (blocksItem.currentDirectionEnum) {
case this.DirectionEnum.left:
if (minItemPosX == 0)
allowDown = false;
break;
case this.DirectionEnum.right:
if (maxItemPosX == this.HorizontalNum - 1)
allowDown = false;
break;
}
}
return allowDown;
},
NoBlocksInthePlace: function() {
var gameMap = this.GameMap;
var allowDown = true;
var blocksItem = this.GetActiviteBlocks();
var itemPosArray = this._getBlocksItemPosArray(blocksItem);
return this._isOverMapChild(itemPosArray, blocksItem, false) ? false : true;
},
_isOverMapChild: function(itemPosArray, blocksItem, isDown) {
var isOverMapChild = false;
var itemPosYArray = itemPosArray.ItemPosYArray;
var itemPosXArray = itemPosArray.ItemPosXArray;
for (var i = 0; i < itemPosYArray.length; i++) {
var itemX = itemPosXArray[i];
var itemY = itemPosYArray[i];
if (blocksItem.currentDirectionEnum == this.DirectionEnum.left && !isDown) {
itemX--;
if (itemX >= 0 && itemY >= 0) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
if (blocksItem.currentDirectionEnum == this.DirectionEnum.right && !isDown) {
itemX++;
if (itemX < this.HorizontalNum && itemY >= 0) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
if (isDown) {
itemY++;
// if (itemPosYArray[i] > 0 && itemY < this.VerticalNum) {
if (itemY >= 0 && itemY < this.VerticalNum) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
}
return isOverMapChild;
},
_allowBlocksDown: function(itemPosArray, blocksItem, isDown) {
var isOverMapChild = this._isOverMapChild(itemPosArray, blocksItem, isDown);
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var maxItemPosY = itemPosArray.ItemPosYArray[itemPosArray.ItemPosYArray.length - 1];
var isToBoard = (maxItemPosY == this.VerticalNum - 1);
return !(isToBoard || isOverMapChild);
},
_getBlocksItemPosArray: function(blocksItem) {
var itemPosXArray = [];
var itemPosYArray = [];
for (var i = 0; i < blocksItem.blocks.length; i++) {
itemPosXArray.push(blocksItem.blocks[i].x + blocksItem.x);
itemPosYArray.push(blocksItem.blocks[i].y + blocksItem.y);
}
return { ItemPosXArray: itemPosXArray, ItemPosYArray: itemPosYArray };
},
_getRelativeBlocksItemPosArray: function(blocksItem) {
var itemPosXArray = [];
var itemPosYArray = [];
for (var i = 0; i < blocksItem.blocks.length; i++) {
itemPosXArray.push(blocksItem.blocks[i].x);
itemPosYArray.push(blocksItem.blocks[i].y);
}
return { ItemPosXArray: itemPosXArray, ItemPosYArray: itemPosYArray };
},
GetBlocksInitPos: function(blocks) {
var blocksItem = null;
if (!blocks)
blocksItem = this.GetActiviteBlocks();
else
blocksItem = blocks;
var itemPosArray = this._getRelativeBlocksItemPosArray(blocksItem);
itemPosArray.ItemPosXArray = itemPosArray.ItemPosXArray.filter();
itemPosArray.ItemPosYArray = itemPosArray.ItemPosYArray.filter();
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var childsNumX = itemPosArray.ItemPosXArray.length;
var childsNumY = itemPosArray.ItemPosYArray.length;
var maxItemPosX = itemPosArray.ItemPosXArray[childsNumX - 1];
var minItemPosX = itemPosArray.ItemPosXArray[0];
var maxItemPosY = itemPosArray.ItemPosYArray[childsNumY - 1];
var minItemPosY = itemPosArray.ItemPosYArray[0];
if (blocks) {
return { x: (this.SmallGridNum - childsNumX - 1) / 2 + 0.5 - minItemPosX, y: (this.SmallGridNum - childsNumY - 1) / 2 + 0.5 - minItemPosY };
}
else {
return { x: parseInt((this.HorizontalNum - childsNumX - 1) / 2) + 1 - minItemPosX, y: -(childsNumY + minItemPosY) };
}
},
GetNextActiviteBrocks: function() {
var blocks = this.GetActiviteBlocks();
var index = -1;
for (var i = 0; i < this.BlocksObj.length; i++) {
if (this.BlocksObj[i].isInGameMap) {
this.BlocksObj.removeAt(i);
}
}
this.BlocksObj[0].isInGameMap = true;
var itemPos = this.GetBlocksInitPos();
this.BlocksObj[0].x = itemPos.x;
this.BlocksObj[0].y = itemPos.y;
this.BlocksObj[0].AddToGameMap(this.BlocksObj[0].color, this.BlocksObj[0].isInGameMap);
this.CreateBlocks();
},
AddToGameMapGrid: function() {
var blocks = this.GetActiviteBlocks();
blocks.UseGrid(this.GameMap, blocks);
},
GetScore: function() {
var gameMap = this.GameMap;
var count = 0;
var rowIndexArray = [];
for (var i = 0; i < this.VerticalNum; i++) {
var entireRow = true;
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] == null) {
entireRow = false;
}
}
if (entireRow) {
count++;
rowIndexArray.push(i);
}
}
var scoreElement = document.getElementById("score");
var currentScore = 0;
var score = parseInt(scoreElement.innerText);
switch (count) {
case 1:
currentScore = this.ScoreStrategy[0];
break;
case 2:
currentScore = this.ScoreStrategy[1];
break;
case 3:
currentScore = this.ScoreStrategy[2];
break;
case 4:
currentScore = this.ScoreStrategy[3];
break;
}
if (count >= 1) {
this.IsInAddScore = true;
this._FreeMapGrid(rowIndexArray);
var totalScore = currentScore + score;
scoreElement.innerText = totalScore;
this.CheckTheLevel();
this.IsInAddScore = false;
}
},
CheckTheLevel: function() {
var currentScore = parseInt(document.getElementById("score").innerText);
var speedList = document.getElementById("speed");
var currentLevel = parseInt(speedList.options[speedList.selectedIndex].text) - 1;
var levelScore = this.LevelScores[currentLevel];
if (currentScore >= levelScore) {
if (currentLevel < this.LevelScores.length) {
var element = document.getElementById("gameOver");
element.innerText = "恭喜你通过" + (speedList.selectedIndex + 1) + "关";
element.style.display = "block";
this.PauseGame();
document.getElementById("btnStart").disabled = true;
document.getElementById("speed").disabled = true;
this._goToNextLevel.delay(3000, speedList);
}
else {
this._finishAllTheLevel(element);
}
}
},
_goToNextLevel: function(element) {
Sys.IsPlay = true;
document.getElementById("btnStart").disabled = false;
document.getElementById("speed").disabled = false;
var speedList = document.getElementById("speed");
speedList.options[speedList.selectedIndex + 1].selected = true;
Sys.CurrentSpeed = Sys.Speeds[speedList.selectedIndex + 1];
Sys.Timer = setInterval("moving()", Sys.CurrentSpeed);
var element = document.getElementById("gameOver");
element.style.display = "none";
},
_finishAllTheLevel: function() {
this.PauseGame();
},
_FreeMapGrid: function(rowIndexArray) {
var gameMap = this.GameMap;
var startIndex = rowIndexArray[0];
var len = rowIndexArray.length;
var maxIndex = startIndex + len - 1;
for (var i = startIndex; i <= maxIndex; i++) {
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] != null) {
document.getElementById("map").removeChild(gameMap[i][j][this.TypeEnum.blocks].domElement);
gameMap[i][j][this.TypeEnum.blocks] = null;
}
}
}
this.ResetMapGrid(rowIndexArray);
},
ResetMapGrid: function(rowIndexArray) {
var gameMap = this.GameMap;
var maxIndex = rowIndexArray[0];
var len = rowIndexArray.length;
for (var i = maxIndex - 1; i >= 0; i--) {
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] != null) {
this._resetMapElement(gameMap[i][j][this.TypeEnum.blocks].domElement, len);
gameMap[i + len][j][this.TypeEnum.blocks] = gameMap[i][j][this.TypeEnum.blocks];
gameMap[i][j][this.TypeEnum.blocks] = null;
}
}
}
},
_resetMapElement: function(element, len) {
element.style.top = (parseInt(element.style.top) + 28 * len) + "px";
},
AllowChangeShape: function() {
var blockItem = this.GetActiviteBlocks();
var gameMap = this.GameMap;
var blocksPoses = this.BlocksShapeMaps[blockItem.blocksEnum];
var num = this.BlocksStateNum[blockItem.blocksEnum];
var currentState1 = -1;
if (blockItem.currentState == num - 1) {
currentState1 = 0
}
else {
currentState1 = blockItem.currentState + 1;
}
var blocksPos = blocksPoses[currentState1];
var k = 0;
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = blockItem.blocks[k];
var itemX = blockItem.x + blocksPos[i][j][0];
var itemY = blockItem.y + blocksPos[i][j][1];
if ((itemX > this.HorizontalNum - 1) || (itemX < 0) || (itemY > this.VerticalNum - 1))
return false;
else if (itemY >= 0 && gameMap[itemY][itemX] != null && gameMap[itemY][itemX][this.TypeEnum.blocks] != null)
return false;
}
k++;
}
return true;
},
InitSpeed: function() {
var speedList = document.getElementById("speed");
if(speedList.options.length==0)
{
for (var i = 0; i < this.Speeds.length; i++) {
var varItem = new Option(i + 1, this.Speeds[i]);
speedList.options.add(varItem);
}
}
this.SetSpeedSelected();
},
SetSpeedSelected: function() {
var speedList = document.getElementById("speed");
for (var i = 0; i < speedList.options.length; i++) {
if (speedList.options[i].value == this.CurrentSpeed) {
speedList.options[i].selected = true;
break;
}
}
},
GameOver: function() {
this.IsGameOver = true;
this.PauseGame();
var element = document.getElementById("gameOver");
element.innerText = "Game Over!";
element.style.display = "block";
document.getElementById("btnStart").value = "try again";
},
PlayGame: function() {
this.IsPlay = true;
if (!this.IsFirstPlay) {
this.Timer = setInterval("moving()", this.CurrentSpeed);
return;
}
if (this.BlocksObj.length == 1) {
var blocksItem = this.BlocksObj[0];
blocksItem.isInGameMap = true;
var itemPos = this.GetBlocksInitPos();
blocksItem.x = itemPos.x;
blocksItem.y = itemPos.y;
blocksItem.AddToGameMap(blocksItem.color, blocksItem.isInGameMap, false);
}
this.CreateBlocks();
this.NaturalMove();
},
PauseGame: function() {
this.IsPlay = false;
clearInterval(this.Timer);
},
CreateBlocks: function() {
var num = this.BlocksEnum.length;
var currentNum = num.getRandom();
var blocks = null;
blocks = new Blocks(0, 0, this.BlocksNum[currentNum], this.BlocksStateNum[currentNum], currentNum, this.ColorEnum[currentNum]);
blocks.Init();
if (this.BlocksObj.length == 3) {
Sys.BlocksObj.pop();
}
Sys.BlocksObj.push(blocks);
},
NaturalMove: function() {
if (!this.IsInAddScore)
this.Timer = setInterval("moving()", Sys.CurrentSpeed);
},
ClearElementsFormMapGrid: function() {
var map = document.getElementById("map");
var smallMap = document.getElementById("smallMap");
this.RemoveAllChilds(map);
this.RemoveAllChilds(smallMap);
},
RemoveAllChilds: function(element) {
var len = element.childNodes.length;
for (var i = len - 1; i >= 0; i--) {
element.removeChild(element.childNodes[i]);
}
}
}
function Base() {
}
Base.prototype.AddToSmallMap = function(map, colorEnum, isInGameMap) {
for (var i = 0; i < this.blocks.length; i++) {
var element = document.createElement("DIV");
document.getElementById("smallMap").appendChild(element);
this.blocksElement.push(element);
element.style.position = "absolute";
element.style.left = ((this.x + this.blocks[i].x) * 28) + "px";
element.style.top = ((this.y + this.blocks[i].y) * 28) + "px";
element.style.backgroundPositionX = colorEnum[0];
element.style.backgroundPositionY = colorEnum[1];
this.blocks[i].domElement = element;
}
}
Base.prototype.AddToGameMap = function(colorEnum, isInGameMap,isMoving) {
for (var i = 0; i < this.blocks.length; i++) {
var element = this.blocksElement[i];
if (!isMoving)
document.getElementById("map").appendChild(element);
element.style.position = "absolute";
element.style.left = ((this.x + this.blocks[i].x) * 28) + "px";
element.style.top = ((this.y + this.blocks[i].y) * 28) + "px";
element.style.backgroundPositionX = colorEnum[0];
element.style.backgroundPositionY = colorEnum[1];
}
}
Base.prototype.UseGrid = function(map, blocksItem) {
for (var i = 0; i < blocksItem.blocks.length; i++) {
var itemX = blocksItem.x + blocksItem.blocks[i].x;
var itemY = blocksItem.y + blocksItem.blocks[i].y;
if (blocksItem.y < 0) {
Sys.GameOver();
return;
}
if (map[itemY][itemX][this.type] != null) {
map[itemY][itemX][this.type] = blocksItem.blocks[i];
}
else {
map[itemY][itemX] = {};
map[itemY][itemX][this.type] = blocksItem.blocks[i];
}
}
return this;
}
function Block(x, y, colorEnum,isInGameMap) {
this.x = x;
this.y = y;
this.color = colorEnum;
this.type = Sys.TypeEnum.block;
this.isInGameMap = isInGameMap;
this.domElement = null;
}
function Blocks(x, y, gridNum, state, blocksEnum,colorEnum) {
this.x = x;
this.y = y;
this.gridNum = gridNum;
this.state = state;
this.blocksEnum = blocksEnum;
this.color = colorEnum;
this.type = Sys.TypeEnum.blocks;
this.blocks = [];
this.blocksElement = [];
this.currentState = 0;
this.isInGameMap = false;
this.currentDirectionEnum = Sys.DirectionEnum.down;
}
Blocks.prototype = new Base();
Blocks.prototype.Init = function() {
var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
var currentState1 = Sys.BlocksStateNum[this.blocksEnum].getRandom();
this.currentState = currentState1;
var blocksPos = blocksPoses[currentState1];
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = new Block(blocksPos[i][j][0], blocksPos[i][j][1], this.color, this.isInGameMap);
this.blocks.push(block);
}
}
var itemPos = Sys.GetBlocksInitPos(this);
this.x = itemPos.x;
this.y = itemPos.y;
this.AddToSmallMap(Sys.BlocksMap, this.color, this.isInGameMap);
}
Blocks.prototype.ChangeShape = function() {
var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
var num = Sys.BlocksStateNum[this.blocksEnum];
if (this.currentState == num - 1) {
this.currentState = 0
}
else {
this.currentState++;
}
var blocksPos = blocksPoses[this.currentState];
var k = 0;
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = this.blocks[k];
block.x = blocksPos[i][j][0];
block.y = blocksPos[i][j][1];
k++;
}
}
this.AddToGameMap(this.color, this.isInGameMap, true);
}
Number.prototype.getRandom = function() {
var num = this;
var i = num + 1;
while (i >= num) {
i = Math.round(Math.random()*10);
}
return i;
}
Array.prototype.sorts = function() {
return this.sort(compare);
}
function compare(a, b) {
return a - b;
}
Array.prototype.removeAt = function(dx) {
if (isNaN(dx) || dx > this.length) { return false; }
for (var i = 0, n = 0; i < this.length; i++) {
if (this[i] != this[dx]) {
this[n++] = this[i]
}
}
this.length -= 1
}
Array.prototype.filter = function() {
var arr = [];
for (var i = 0; i < this.length; i++) {
if (!arr.contains(this[i])) {
arr.push(this[i]);
}
}
return arr;
}
Array.prototype.contains = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item) {
return true; ;
}
}
return false;
}
Function.prototype.delay=function(time)
{
var timer = setTimeout(this,time);
}
window.onload = InitGame;
function InitGame() {
Sys = new sys();
Sys.BlocksObj = [];
Sys.ClearElementsFormMapGrid();
Sys.InitSpeed();
Sys.CreateGameMap();
Sys.CreateBlocksShapeMaps();
Sys.CreateBlocks();
}
function GameStart(element) {
Sys.IsBegin = true;
if (element.value == "start") {
element.value = "pause";
Sys.PlayGame();
Sys.IsFirstPlay = false;
}
else if(element.value =="pause" ){
element.value = "start"
Sys.PauseGame();
}
else
{
Sys = null;
InitGame();
element.value = "pause";
var elements = document.getElementById("gameOver");
document.getElementById("score").innerText ="0";
elements.style.display = "none";
Sys.PlayGame();
Sys.IsFirstPlay = false;
}
}
function moving() {
Sys.IsMoving = true;
var blocks = Sys.GetActiviteBlocks();
if (blocks) {
if (!Sys.AllowBlocksMove(true) && !Sys.IsKeyDown) {
blocks.y;
Sys.AddToGameMapGrid();
Sys.GetScore();
Sys.GetNextActiviteBrocks();
}
else {
blocks.y++;
blocks.AddToGameMap(blocks.color, blocks.isInGameMap);
}
}
}
function ChangeSpeed(e) {
var speedlist = document.getElementById("speed");
Sys.CurrentSpeed = speedlist.options[speedlist.selectedIndex].value;
if(!Sys.IsGameOver)
{
clearInterval(Sys.Timer);
Sys.Timer = setInterval("moving()", Sys.CurrentSpeed);
}
}
function keyDown(e) {
if (Sys.IsGameOver || !Sys.IsPlay) return;
var blocks = Sys.GetActiviteBlocks();
var flag = false;
if (!blocks) return;
if (e.keyCode == 37) //向左
{
blocks.currentDirectionEnum = Sys.DirectionEnum.left;
if(Sys.AllowBlocksMove(false) && Sys.NoBlocksInthePlace())
{
blocks.x--;
}
if (blocks.x != 0)
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
else if (e.keyCode == 38) //向上
{
blocks.currentDirectionEnum = Sys.DirectionEnum.up;
if (Sys.AllowChangeShape()) {
blocks.ChangeShape(false);
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
}
else if (e.keyCode == 39) //向右
{
blocks.currentDirectionEnum = Sys.DirectionEnum.right;
var oldX = blocks.x;
if(Sys.AllowBlocksMove(false) && Sys.NoBlocksInthePlace())
{
blocks.x++;
}
if (blocks.x != oldX)
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
else if (e.keyCode == 40) //向下
{
Sys.IsKeyDown = true;
if (!Sys.AllowBlocksMove(true)) {
blocks.y = blocks.y;
Sys.AddToGameMapGrid();
Sys.GetScore();
Sys.GetNextActiviteBrocks();
}
else {
blocks.y++;
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
Sys.IsKeyDown = false;
}
}
</script>
<style type="text/css">
body
{}{
background-color: #ffffff;
overflow: hidden;
font-size: 14px;
}
.gameZone
{}{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 550px;
background-color: white;
}
.mask
{}{
position: absolute;
left: 100px;
top: 0px;
width: 300px;
height: 20px;
background-color: White;
border: solid 0px;
z-index: 5;
}
.map
{}{
position: absolute;
left: 100px;
top: 20px;
width: 280px;
height: 504px;
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris_grid.gif);
border: solid 3px green;
}
.gameOver
{}{
position: absolute;
left: 100px;
top: 20px;
width: 280px;
height: 504px;
font-weight: 800;
font-size: xx-large;
color: Red;
text-align: center;
border: solid 3px;
line-height: 420px;
display: none;
filter: Alpha(Opacity=80);
background-color: pink;
}
.map div
{}{
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris.gif);
width: 28px;
background-repeat: no-repeat;
position: absolute;
height: 28px;
}
.smallMap
{}{
position: absolute;
left: 400px;
top: 20px;
width: 168px;
height: 168px;
background-color: pink;
border: solid 2px green;
}
.smallMap div
{}{
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris.gif);
width: 28px;
background-repeat: no-repeat;
position: absolute;
height: 28px;
}
.start
{}{
position: absolute;
left: 400px;
top: 240px;
width: 168px;
height: 40px;
}
.scoreSpeed
{}{
position: absolute;
left: 400px;
top: 200px;
width: 190px;
height: 40px;
}
.score
{}{
color: pink;
font-weight: bold;
width: 20px;
height: 20px;
background-color: blue;
padding-left: 10px;
padding-right: 10px;
font-size: medium;
}
.speed
{}{
color: pink;
font-weight: bold;
width: 20px;
height: 20px;
background-color: blue;
padding-left: 5px;
padding-right: 5px;
font-size: medium;
}
.copyright
{}{
position: absolute;
left: 400px;
top: 280px;
word-break: break-all;
width: 160px;
height: 225px;
border: solid 2px green;
padding: 5px;
}
</style>
</head>
<body onkeydown="keyDown(event)">
<div class="gameZone">
<div id="mask" class="mask">
</div>
<div id="map" class="map">
</div>
<div id="gameOver" class="gameOver">
</div>
<div id="smallMap" class="smallMap">
</div>
<div id="scoreSpeed" class="scoreSpeed">
得分:<span id="score" class="score">0</span></div>
<div id="start" class="start">
<input type="button" id="btnStart" value="start" onclick="GameStart(this);" />
级别:<select id="speed" onchange="ChangeSpeed();"></select>
</div>
<div id="copyright" class="copyright">
<b>
<center>
版权所有</center>
</b>
<br />
此俄罗斯方块由高山流水开发,欢迎各位使用, 如有bug或者好的意见,请给我留言,谢谢支持! 另如需转载,请注明出处!
<br />
<br />
作者:<a href="http://blog.csdn.net/46539492" target="_blank">高山流水</a><br />
QQ:21243468
</div>
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>俄罗斯方块</title>
<script language="javascript" type="text/javascript">
var Sys = null;
function sys()
{
}
sys.prototype = {
GameMap: [],
BlocksMap: [],
SmallMap: [],
BlocksObj: [],
Timer: null,
HorizontalNum: 10,
VerticalNum: 18,
IsBegin: false,
IsMoving: false,
IsGameOver: false,
ScoreStrategy: [100, 300, 500, 800],
LevelScores: [5000, 20000, 40000, 60000, 80000, 100000, 120000, 140000, 160000, 200000],
TotalScore: 0,
IsInAddScore: false,
IsKeyDown: false,
IsPlay: false,
IsFirstPlay: true,
SmallGridNum: 6,
DirectionEnum: { left: 0, right: 1, up: 2, down: 3 },
Speeds: [1000, 900, 800, 700, 600, 500, 400, 300, 200, 100],
CurrentSpeed: 1000,
TypeEnum: { none: 0, block: 1, blocks: 2 },
BlocksEnum: [0, 1, 2, 3, 4, 5, 6,7,8,9], //0为LL,1为LR,2为T,3为ZL,4为ZR,5为I,6为F,7为长T
BlocksNum: [4, 4, 3, 3, 3, 4, 2,5,5,5],
BlocksStateNum: [4, 4, 4, 2, 2, 2, 1,4,4,2],
BlocksShapeMaps: [],
ColorEnum: [[0, 0], [-28, 0], [-56, 0], [-84, 0], [-112, 0], [-140, 0], [-168, 0],[0, 0], [-28, 0], [-56, 0]],
CreateGameMap: function() {
for (var i = 0; i < this.VerticalNum; i++) {
this.GameMap.push([]);
for (var j = 0; j < this.HorizontalNum; j++) {
this.GameMap[i][j] = {};
this.GameMap[i][j][Sys.TypeEnum.blocks] = null;
}
}
},
CreateBlocksShapeMaps: function() {
for (var i = 0; i < this.BlocksEnum.length; i++) {
this._createBlocksShapeMap(i);
}
},
_createBlocksShapeMap: function(index) {
var blocksPoses = [];
switch (index) {
case 0:
var blocksPos1 = [[[2,1]],[[0,2],[1,2],[2,2]]];
var blocksPos2 = [[[1,0]],[[1,1]],[[1,2],[2,2]]];
var blocksPos3 = [[[0,1],[1,1],[2,1]],[[0,2]]];
var blocksPos4 = [[[1,0],[2,0]],[[2,1]],[[2,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 1:
var blocksPos1 = [[[2, 0]], [[2, 1]], [[1, 2], [2, 2]]];
var blocksPos2 = [[[0, 1]], [[0, 2], [1, 2]], [[2, 2]]];
var blocksPos3 = [[[0, 0], [1, 0]], [[0, 1]], [[0, 2]]];
var blocksPos4 = [[[0, 1], [1, 1], [2, 1]], [[2, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 2:
var blocksPos1 = [[[0, 0], [1, 0], [2, 0]], [[1, 1]]];
var blocksPos2 = [[[1, 0]], [[0, 1], [1, 1]], [[1, 2]]];
var blocksPos3 = [[[1, 1]], [[0, 2], [1, 2], [2, 2]]];
var blocksPos4 = [[[0, 0]], [[0, 1], [1, 1]], [[0, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 3:
var blocksPos1 = [[[0, 0]], [[0, 1], [1, 1]], [[1, 2]]];
var blocksPos2 = [[[1, 1], [2, 1]], [[0, 2], [1, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 4:
var blocksPos1 = [[[1, 0]], [[0, 1], [1, 1]], [[0, 2]]];
var blocksPos2 = [[[0, 1], [1, 1]], [[1, 2], [2, 2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 5:
var blocksPos1 = [[[0, 0]], [[0, 1]], [[0, 2]], [[0, 3]]];
var blocksPos2 = [[[0, 3]], [[1, 3]], [[2, 3]], [[3, 3]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
case 6:
var blocksPos = [[[0, 0], [0, 1]], [[1, 0], [1, 1]]];
blocksPoses.push(blocksPos);
break;
case 7:
var blocksPos1 = [[[0,0],[1,0],[2,0]],[[1,1]],[[1,2]]];
var blocksPos2 = [[[2,0]],[[0,1],[1,1],[2,1]],[[2,2]]];
var blocksPos3 = [[[1,0]],[[1,1]],[[0,2],[1,2],[2,2]]];
var blocksPos4 = [[[0,0]],[[0,1],[1,1],[2,1]],[[0,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 8:
var blocksPos1 = [[[0,1],[1,1],[2,1]],[[0,2]],[[2,2]]];
var blocksPos2 = [[[1,0],[2,0]],[[2,1]],[[1,2],[2,2]]];
var blocksPos3 = [[[0,1],[2,1]],[[0,2],[1,2],[2,2]]];
var blocksPos4 = [[[1,0],[2,0]],[[1,1]],[[1,2],[2,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
blocksPoses.push(blocksPos3);
blocksPoses.push(blocksPos4);
break;
case 9:
var blocksPos1 = [[[0,0],[1,0]],[[1,1]],[[1,2],[2,2]]];
var blocksPos2 = [[[2,0]],[[0,1],[1,1],[2,1]],[[0,2]]];
blocksPoses.push(blocksPos1);
blocksPoses.push(blocksPos2);
break;
}
Sys.BlocksShapeMaps.push(blocksPoses);
},
GetInactivateBlocks: function() {
for (var i = 0; i < Sys.BlocksObj.length; i++) {
if (!Sys.BlocksObj[i].isInGameMap) {
return Sys.BlocksObj[i];
}
}
return null;
},
GetActiviteBlocks: function() {
for (var i = 0; i < this.BlocksObj.length; i++) {
if (this.BlocksObj[i].isInGameMap) {
return this.BlocksObj[i];
}
}
return null;
},
AllowBlocksMove: function(isDown) {
var blocksItem = this.GetActiviteBlocks();
var itemPosArray = this._getBlocksItemPosArray(blocksItem);
var allowDown = true;
if (isDown) {
allowDown = this._allowBlocksDown(itemPosArray, blocksItem, isDown);
}
else {
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var maxItemPosX = itemPosArray.ItemPosXArray[itemPosArray.ItemPosXArray.length - 1];
var minItemPosX = itemPosArray.ItemPosXArray[0];
var maxItemPosY = itemPosArray.ItemPosYArray[itemPosArray.ItemPosYArray.length - 1];
var minItemPosY = itemPosArray.ItemPosYArray[0];
switch (blocksItem.currentDirectionEnum) {
case this.DirectionEnum.left:
if (minItemPosX == 0)
allowDown = false;
break;
case this.DirectionEnum.right:
if (maxItemPosX == this.HorizontalNum - 1)
allowDown = false;
break;
}
}
return allowDown;
},
NoBlocksInthePlace: function() {
var gameMap = this.GameMap;
var allowDown = true;
var blocksItem = this.GetActiviteBlocks();
var itemPosArray = this._getBlocksItemPosArray(blocksItem);
return this._isOverMapChild(itemPosArray, blocksItem, false) ? false : true;
},
_isOverMapChild: function(itemPosArray, blocksItem, isDown) {
var isOverMapChild = false;
var itemPosYArray = itemPosArray.ItemPosYArray;
var itemPosXArray = itemPosArray.ItemPosXArray;
for (var i = 0; i < itemPosYArray.length; i++) {
var itemX = itemPosXArray[i];
var itemY = itemPosYArray[i];
if (blocksItem.currentDirectionEnum == this.DirectionEnum.left && !isDown) {
itemX--;
if (itemX >= 0 && itemY >= 0) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
if (blocksItem.currentDirectionEnum == this.DirectionEnum.right && !isDown) {
itemX++;
if (itemX < this.HorizontalNum && itemY >= 0) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
if (isDown) {
itemY++;
// if (itemPosYArray[i] > 0 && itemY < this.VerticalNum) {
if (itemY >= 0 && itemY < this.VerticalNum) {
if (this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
isOverMapChild = true;
break;
}
}
}
}
return isOverMapChild;
},
_allowBlocksDown: function(itemPosArray, blocksItem, isDown) {
var isOverMapChild = this._isOverMapChild(itemPosArray, blocksItem, isDown);
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var maxItemPosY = itemPosArray.ItemPosYArray[itemPosArray.ItemPosYArray.length - 1];
var isToBoard = (maxItemPosY == this.VerticalNum - 1);
return !(isToBoard || isOverMapChild);
},
_getBlocksItemPosArray: function(blocksItem) {
var itemPosXArray = [];
var itemPosYArray = [];
for (var i = 0; i < blocksItem.blocks.length; i++) {
itemPosXArray.push(blocksItem.blocks[i].x + blocksItem.x);
itemPosYArray.push(blocksItem.blocks[i].y + blocksItem.y);
}
return { ItemPosXArray: itemPosXArray, ItemPosYArray: itemPosYArray };
},
_getRelativeBlocksItemPosArray: function(blocksItem) {
var itemPosXArray = [];
var itemPosYArray = [];
for (var i = 0; i < blocksItem.blocks.length; i++) {
itemPosXArray.push(blocksItem.blocks[i].x);
itemPosYArray.push(blocksItem.blocks[i].y);
}
return { ItemPosXArray: itemPosXArray, ItemPosYArray: itemPosYArray };
},
GetBlocksInitPos: function(blocks) {
var blocksItem = null;
if (!blocks)
blocksItem = this.GetActiviteBlocks();
else
blocksItem = blocks;
var itemPosArray = this._getRelativeBlocksItemPosArray(blocksItem);
itemPosArray.ItemPosXArray = itemPosArray.ItemPosXArray.filter();
itemPosArray.ItemPosYArray = itemPosArray.ItemPosYArray.filter();
itemPosArray.ItemPosXArray.sorts();
itemPosArray.ItemPosYArray.sorts();
var childsNumX = itemPosArray.ItemPosXArray.length;
var childsNumY = itemPosArray.ItemPosYArray.length;
var maxItemPosX = itemPosArray.ItemPosXArray[childsNumX - 1];
var minItemPosX = itemPosArray.ItemPosXArray[0];
var maxItemPosY = itemPosArray.ItemPosYArray[childsNumY - 1];
var minItemPosY = itemPosArray.ItemPosYArray[0];
if (blocks) {
return { x: (this.SmallGridNum - childsNumX - 1) / 2 + 0.5 - minItemPosX, y: (this.SmallGridNum - childsNumY - 1) / 2 + 0.5 - minItemPosY };
}
else {
return { x: parseInt((this.HorizontalNum - childsNumX - 1) / 2) + 1 - minItemPosX, y: -(childsNumY + minItemPosY) };
}
},
GetNextActiviteBrocks: function() {
var blocks = this.GetActiviteBlocks();
var index = -1;
for (var i = 0; i < this.BlocksObj.length; i++) {
if (this.BlocksObj[i].isInGameMap) {
this.BlocksObj.removeAt(i);
}
}
this.BlocksObj[0].isInGameMap = true;
var itemPos = this.GetBlocksInitPos();
this.BlocksObj[0].x = itemPos.x;
this.BlocksObj[0].y = itemPos.y;
this.BlocksObj[0].AddToGameMap(this.BlocksObj[0].color, this.BlocksObj[0].isInGameMap);
this.CreateBlocks();
},
AddToGameMapGrid: function() {
var blocks = this.GetActiviteBlocks();
blocks.UseGrid(this.GameMap, blocks);
},
GetScore: function() {
var gameMap = this.GameMap;
var count = 0;
var rowIndexArray = [];
for (var i = 0; i < this.VerticalNum; i++) {
var entireRow = true;
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] == null) {
entireRow = false;
}
}
if (entireRow) {
count++;
rowIndexArray.push(i);
}
}
var scoreElement = document.getElementById("score");
var currentScore = 0;
var score = parseInt(scoreElement.innerText);
switch (count) {
case 1:
currentScore = this.ScoreStrategy[0];
break;
case 2:
currentScore = this.ScoreStrategy[1];
break;
case 3:
currentScore = this.ScoreStrategy[2];
break;
case 4:
currentScore = this.ScoreStrategy[3];
break;
}
if (count >= 1) {
this.IsInAddScore = true;
this._FreeMapGrid(rowIndexArray);
var totalScore = currentScore + score;
scoreElement.innerText = totalScore;
this.CheckTheLevel();
this.IsInAddScore = false;
}
},
CheckTheLevel: function() {
var currentScore = parseInt(document.getElementById("score").innerText);
var speedList = document.getElementById("speed");
var currentLevel = parseInt(speedList.options[speedList.selectedIndex].text) - 1;
var levelScore = this.LevelScores[currentLevel];
if (currentScore >= levelScore) {
if (currentLevel < this.LevelScores.length) {
var element = document.getElementById("gameOver");
element.innerText = "恭喜你通过" + (speedList.selectedIndex + 1) + "关";
element.style.display = "block";
this.PauseGame();
document.getElementById("btnStart").disabled = true;
document.getElementById("speed").disabled = true;
this._goToNextLevel.delay(3000, speedList);
}
else {
this._finishAllTheLevel(element);
}
}
},
_goToNextLevel: function(element) {
Sys.IsPlay = true;
document.getElementById("btnStart").disabled = false;
document.getElementById("speed").disabled = false;
var speedList = document.getElementById("speed");
speedList.options[speedList.selectedIndex + 1].selected = true;
Sys.CurrentSpeed = Sys.Speeds[speedList.selectedIndex + 1];
Sys.Timer = setInterval("moving()", Sys.CurrentSpeed);
var element = document.getElementById("gameOver");
element.style.display = "none";
},
_finishAllTheLevel: function() {
this.PauseGame();
},
_FreeMapGrid: function(rowIndexArray) {
var gameMap = this.GameMap;
var startIndex = rowIndexArray[0];
var len = rowIndexArray.length;
var maxIndex = startIndex + len - 1;
for (var i = startIndex; i <= maxIndex; i++) {
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] != null) {
document.getElementById("map").removeChild(gameMap[i][j][this.TypeEnum.blocks].domElement);
gameMap[i][j][this.TypeEnum.blocks] = null;
}
}
}
this.ResetMapGrid(rowIndexArray);
},
ResetMapGrid: function(rowIndexArray) {
var gameMap = this.GameMap;
var maxIndex = rowIndexArray[0];
var len = rowIndexArray.length;
for (var i = maxIndex - 1; i >= 0; i--) {
for (var j = 0; j < this.HorizontalNum; j++) {
if (gameMap[i][j][this.TypeEnum.blocks] != null) {
this._resetMapElement(gameMap[i][j][this.TypeEnum.blocks].domElement, len);
gameMap[i + len][j][this.TypeEnum.blocks] = gameMap[i][j][this.TypeEnum.blocks];
gameMap[i][j][this.TypeEnum.blocks] = null;
}
}
}
},
_resetMapElement: function(element, len) {
element.style.top = (parseInt(element.style.top) + 28 * len) + "px";
},
AllowChangeShape: function() {
var blockItem = this.GetActiviteBlocks();
var gameMap = this.GameMap;
var blocksPoses = this.BlocksShapeMaps[blockItem.blocksEnum];
var num = this.BlocksStateNum[blockItem.blocksEnum];
var currentState1 = -1;
if (blockItem.currentState == num - 1) {
currentState1 = 0
}
else {
currentState1 = blockItem.currentState + 1;
}
var blocksPos = blocksPoses[currentState1];
var k = 0;
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = blockItem.blocks[k];
var itemX = blockItem.x + blocksPos[i][j][0];
var itemY = blockItem.y + blocksPos[i][j][1];
if ((itemX > this.HorizontalNum - 1) || (itemX < 0) || (itemY > this.VerticalNum - 1))
return false;
else if (itemY >= 0 && gameMap[itemY][itemX] != null && gameMap[itemY][itemX][this.TypeEnum.blocks] != null)
return false;
}
k++;
}
return true;
},
InitSpeed: function() {
var speedList = document.getElementById("speed");
if(speedList.options.length==0)
{
for (var i = 0; i < this.Speeds.length; i++) {
var varItem = new Option(i + 1, this.Speeds[i]);
speedList.options.add(varItem);
}
}
this.SetSpeedSelected();
},
SetSpeedSelected: function() {
var speedList = document.getElementById("speed");
for (var i = 0; i < speedList.options.length; i++) {
if (speedList.options[i].value == this.CurrentSpeed) {
speedList.options[i].selected = true;
break;
}
}
},
GameOver: function() {
this.IsGameOver = true;
this.PauseGame();
var element = document.getElementById("gameOver");
element.innerText = "Game Over!";
element.style.display = "block";
document.getElementById("btnStart").value = "try again";
},
PlayGame: function() {
this.IsPlay = true;
if (!this.IsFirstPlay) {
this.Timer = setInterval("moving()", this.CurrentSpeed);
return;
}
if (this.BlocksObj.length == 1) {
var blocksItem = this.BlocksObj[0];
blocksItem.isInGameMap = true;
var itemPos = this.GetBlocksInitPos();
blocksItem.x = itemPos.x;
blocksItem.y = itemPos.y;
blocksItem.AddToGameMap(blocksItem.color, blocksItem.isInGameMap, false);
}
this.CreateBlocks();
this.NaturalMove();
},
PauseGame: function() {
this.IsPlay = false;
clearInterval(this.Timer);
},
CreateBlocks: function() {
var num = this.BlocksEnum.length;
var currentNum = num.getRandom();
var blocks = null;
blocks = new Blocks(0, 0, this.BlocksNum[currentNum], this.BlocksStateNum[currentNum], currentNum, this.ColorEnum[currentNum]);
blocks.Init();
if (this.BlocksObj.length == 3) {
Sys.BlocksObj.pop();
}
Sys.BlocksObj.push(blocks);
},
NaturalMove: function() {
if (!this.IsInAddScore)
this.Timer = setInterval("moving()", Sys.CurrentSpeed);
},
ClearElementsFormMapGrid: function() {
var map = document.getElementById("map");
var smallMap = document.getElementById("smallMap");
this.RemoveAllChilds(map);
this.RemoveAllChilds(smallMap);
},
RemoveAllChilds: function(element) {
var len = element.childNodes.length;
for (var i = len - 1; i >= 0; i--) {
element.removeChild(element.childNodes[i]);
}
}
}
function Base() {
}
Base.prototype.AddToSmallMap = function(map, colorEnum, isInGameMap) {
for (var i = 0; i < this.blocks.length; i++) {
var element = document.createElement("DIV");
document.getElementById("smallMap").appendChild(element);
this.blocksElement.push(element);
element.style.position = "absolute";
element.style.left = ((this.x + this.blocks[i].x) * 28) + "px";
element.style.top = ((this.y + this.blocks[i].y) * 28) + "px";
element.style.backgroundPositionX = colorEnum[0];
element.style.backgroundPositionY = colorEnum[1];
this.blocks[i].domElement = element;
}
}
Base.prototype.AddToGameMap = function(colorEnum, isInGameMap,isMoving) {
for (var i = 0; i < this.blocks.length; i++) {
var element = this.blocksElement[i];
if (!isMoving)
document.getElementById("map").appendChild(element);
element.style.position = "absolute";
element.style.left = ((this.x + this.blocks[i].x) * 28) + "px";
element.style.top = ((this.y + this.blocks[i].y) * 28) + "px";
element.style.backgroundPositionX = colorEnum[0];
element.style.backgroundPositionY = colorEnum[1];
}
}
Base.prototype.UseGrid = function(map, blocksItem) {
for (var i = 0; i < blocksItem.blocks.length; i++) {
var itemX = blocksItem.x + blocksItem.blocks[i].x;
var itemY = blocksItem.y + blocksItem.blocks[i].y;
if (blocksItem.y < 0) {
Sys.GameOver();
return;
}
if (map[itemY][itemX][this.type] != null) {
map[itemY][itemX][this.type] = blocksItem.blocks[i];
}
else {
map[itemY][itemX] = {};
map[itemY][itemX][this.type] = blocksItem.blocks[i];
}
}
return this;
}
function Block(x, y, colorEnum,isInGameMap) {
this.x = x;
this.y = y;
this.color = colorEnum;
this.type = Sys.TypeEnum.block;
this.isInGameMap = isInGameMap;
this.domElement = null;
}
function Blocks(x, y, gridNum, state, blocksEnum,colorEnum) {
this.x = x;
this.y = y;
this.gridNum = gridNum;
this.state = state;
this.blocksEnum = blocksEnum;
this.color = colorEnum;
this.type = Sys.TypeEnum.blocks;
this.blocks = [];
this.blocksElement = [];
this.currentState = 0;
this.isInGameMap = false;
this.currentDirectionEnum = Sys.DirectionEnum.down;
}
Blocks.prototype = new Base();
Blocks.prototype.Init = function() {
var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
var currentState1 = Sys.BlocksStateNum[this.blocksEnum].getRandom();
this.currentState = currentState1;
var blocksPos = blocksPoses[currentState1];
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = new Block(blocksPos[i][j][0], blocksPos[i][j][1], this.color, this.isInGameMap);
this.blocks.push(block);
}
}
var itemPos = Sys.GetBlocksInitPos(this);
this.x = itemPos.x;
this.y = itemPos.y;
this.AddToSmallMap(Sys.BlocksMap, this.color, this.isInGameMap);
}
Blocks.prototype.ChangeShape = function() {
var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
var num = Sys.BlocksStateNum[this.blocksEnum];
if (this.currentState == num - 1) {
this.currentState = 0
}
else {
this.currentState++;
}
var blocksPos = blocksPoses[this.currentState];
var k = 0;
for (var i = 0; i < blocksPos.length; i++) {
for (var j = 0; j < blocksPos[i].length; j++) {
var block = this.blocks[k];
block.x = blocksPos[i][j][0];
block.y = blocksPos[i][j][1];
k++;
}
}
this.AddToGameMap(this.color, this.isInGameMap, true);
}
Number.prototype.getRandom = function() {
var num = this;
var i = num + 1;
while (i >= num) {
i = Math.round(Math.random()*10);
}
return i;
}
Array.prototype.sorts = function() {
return this.sort(compare);
}
function compare(a, b) {
return a - b;
}
Array.prototype.removeAt = function(dx) {
if (isNaN(dx) || dx > this.length) { return false; }
for (var i = 0, n = 0; i < this.length; i++) {
if (this[i] != this[dx]) {
this[n++] = this[i]
}
}
this.length -= 1
}
Array.prototype.filter = function() {
var arr = [];
for (var i = 0; i < this.length; i++) {
if (!arr.contains(this[i])) {
arr.push(this[i]);
}
}
return arr;
}
Array.prototype.contains = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item) {
return true; ;
}
}
return false;
}
Function.prototype.delay=function(time)
{
var timer = setTimeout(this,time);
}
window.onload = InitGame;
function InitGame() {
Sys = new sys();
Sys.BlocksObj = [];
Sys.ClearElementsFormMapGrid();
Sys.InitSpeed();
Sys.CreateGameMap();
Sys.CreateBlocksShapeMaps();
Sys.CreateBlocks();
}
function GameStart(element) {
Sys.IsBegin = true;
if (element.value == "start") {
element.value = "pause";
Sys.PlayGame();
Sys.IsFirstPlay = false;
}
else if(element.value =="pause" ){
element.value = "start"
Sys.PauseGame();
}
else
{
Sys = null;
InitGame();
element.value = "pause";
var elements = document.getElementById("gameOver");
document.getElementById("score").innerText ="0";
elements.style.display = "none";
Sys.PlayGame();
Sys.IsFirstPlay = false;
}
}
function moving() {
Sys.IsMoving = true;
var blocks = Sys.GetActiviteBlocks();
if (blocks) {
if (!Sys.AllowBlocksMove(true) && !Sys.IsKeyDown) {
blocks.y;
Sys.AddToGameMapGrid();
Sys.GetScore();
Sys.GetNextActiviteBrocks();
}
else {
blocks.y++;
blocks.AddToGameMap(blocks.color, blocks.isInGameMap);
}
}
}
function ChangeSpeed(e) {
var speedlist = document.getElementById("speed");
Sys.CurrentSpeed = speedlist.options[speedlist.selectedIndex].value;
if(!Sys.IsGameOver)
{
clearInterval(Sys.Timer);
Sys.Timer = setInterval("moving()", Sys.CurrentSpeed);
}
}
function keyDown(e) {
if (Sys.IsGameOver || !Sys.IsPlay) return;
var blocks = Sys.GetActiviteBlocks();
var flag = false;
if (!blocks) return;
if (e.keyCode == 37) //向左
{
blocks.currentDirectionEnum = Sys.DirectionEnum.left;
if(Sys.AllowBlocksMove(false) && Sys.NoBlocksInthePlace())
{
blocks.x--;
}
if (blocks.x != 0)
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
else if (e.keyCode == 38) //向上
{
blocks.currentDirectionEnum = Sys.DirectionEnum.up;
if (Sys.AllowChangeShape()) {
blocks.ChangeShape(false);
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
}
else if (e.keyCode == 39) //向右
{
blocks.currentDirectionEnum = Sys.DirectionEnum.right;
var oldX = blocks.x;
if(Sys.AllowBlocksMove(false) && Sys.NoBlocksInthePlace())
{
blocks.x++;
}
if (blocks.x != oldX)
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
else if (e.keyCode == 40) //向下
{
Sys.IsKeyDown = true;
if (!Sys.AllowBlocksMove(true)) {
blocks.y = blocks.y;
Sys.AddToGameMapGrid();
Sys.GetScore();
Sys.GetNextActiviteBrocks();
}
else {
blocks.y++;
blocks.AddToGameMap(blocks.color, blocks.isInGameMap, true);
}
Sys.IsKeyDown = false;
}
}
</script>
<style type="text/css">
body
{}{
background-color: #ffffff;
overflow: hidden;
font-size: 14px;
}
.gameZone
{}{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 550px;
background-color: white;
}
.mask
{}{
position: absolute;
left: 100px;
top: 0px;
width: 300px;
height: 20px;
background-color: White;
border: solid 0px;
z-index: 5;
}
.map
{}{
position: absolute;
left: 100px;
top: 20px;
width: 280px;
height: 504px;
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris_grid.gif);
border: solid 3px green;
}
.gameOver
{}{
position: absolute;
left: 100px;
top: 20px;
width: 280px;
height: 504px;
font-weight: 800;
font-size: xx-large;
color: Red;
text-align: center;
border: solid 3px;
line-height: 420px;
display: none;
filter: Alpha(Opacity=80);
background-color: pink;
}
.map div
{}{
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris.gif);
width: 28px;
background-repeat: no-repeat;
position: absolute;
height: 28px;
}
.smallMap
{}{
position: absolute;
left: 400px;
top: 20px;
width: 168px;
height: 168px;
background-color: pink;
border: solid 2px green;
}
.smallMap div
{}{
background-image: url(http://www.cuixiping.com/jsgame/tetris-cxp/tetris_images/tetris.gif);
width: 28px;
background-repeat: no-repeat;
position: absolute;
height: 28px;
}
.start
{}{
position: absolute;
left: 400px;
top: 240px;
width: 168px;
height: 40px;
}
.scoreSpeed
{}{
position: absolute;
left: 400px;
top: 200px;
width: 190px;
height: 40px;
}
.score
{}{
color: pink;
font-weight: bold;
width: 20px;
height: 20px;
background-color: blue;
padding-left: 10px;
padding-right: 10px;
font-size: medium;
}
.speed
{}{
color: pink;
font-weight: bold;
width: 20px;
height: 20px;
background-color: blue;
padding-left: 5px;
padding-right: 5px;
font-size: medium;
}
.copyright
{}{
position: absolute;
left: 400px;
top: 280px;
word-break: break-all;
width: 160px;
height: 225px;
border: solid 2px green;
padding: 5px;
}
</style>
</head>
<body onkeydown="keyDown(event)">
<div class="gameZone">
<div id="mask" class="mask">
</div>
<div id="map" class="map">
</div>
<div id="gameOver" class="gameOver">
</div>
<div id="smallMap" class="smallMap">
</div>
<div id="scoreSpeed" class="scoreSpeed">
得分:<span id="score" class="score">0</span></div>
<div id="start" class="start">
<input type="button" id="btnStart" value="start" onclick="GameStart(this);" />
级别:<select id="speed" onchange="ChangeSpeed();"></select>
</div>
<div id="copyright" class="copyright">
<b>
<center>
版权所有</center>
</b>
<br />
此俄罗斯方块由高山流水开发,欢迎各位使用, 如有bug或者好的意见,请给我留言,谢谢支持! 另如需转载,请注明出处!
<br />
<br />
作者:<a href="http://blog.csdn.net/46539492" target="_blank">高山流水</a><br />
QQ:21243468
</div>
</div>
</body>
</html>