`

俄罗斯方块

    博客分类:
  • ajax
阅读更多
1.初始化下方块组合的图形阶面
//方块的大小
SQUARE_SIZE = 16;
//背景的宽度和高度
BACKGROUND_WIDTH = 336;
BACKGROUND_HEIGHT = 343;
//方块区最左上角的方块位置的水平偏移距离
X_OFFSET = 134;
//方块区最左上角的方块位置的垂直偏移距离
Y_OFFSET = 4;
//下一个方块组合的位置的水平偏移距离
X_OFFSET_NEXT = 47;
//下一个方块组合的位置的垂直偏移距离
Y_OFFSET_NEXT = 8;
//下一个再下一个方块组合的位置的水平偏移距离
X_OFFSET_NEXT_NEXT = 47;
//下一个再下一个方块组合的位置的垂直偏移距离
Y_OFFSET_NEXT_NEXT = 84;

//方块区水平方向的容量
HORIZONTAL_COUNT = 12;
//方块区垂直方向的容量
VERTICAL_COUNT = 21;
//方块在水平方向的出发点(在中间,即索引为5)
INIT_HORIZONTAL_POS = 5;
//方块在垂直方向的出发点(第二格,即索引为1)
INIT_VERTICAL_POS = 1;

//目标对象的漂浮层
LOW_Z_INDEX = 3;
HIGH_Z_INDEX = 10;

//每个方块组合组由4 个方块组成
BLOCKS_SIZE = 4;
//方块组合的类型(7种方块组合和空方块)
SQUARE = 0;
BLOCKS_1 = 1;
BLOCKS_2 = 2;
BLOCKS_3 = 3;
BLOCKS_4 = 4;
BLOCKS_5 = 5;
LONG = 6;
NOTHING = 7;
//方块组合的类型的个数
TYPE_COUNT = 8;
//方块组合的方向的个数
DIRECTION = 4;

//下面的位图路径数组分别代表七种不同的方块及空方块
var squareImagePath = [];
squareImagePath[NOTHING] = "image/nothing.jpg";
squareImagePath[SQUARE] = "image/square0.jpg";
squareImagePath[BLOCKS_1] = "image/square1.jpg";
squareImagePath[BLOCKS_2] = "image/square2.jpg";
squareImagePath[BLOCKS_3] = "image/square3.jpg";
squareImagePath[BLOCKS_4] = "image/square4.jpg";
squareImagePath[BLOCKS_5] = "image/square5.jpg";
squareImagePath[LONG] = "image/square6.jpg";
//下面的位图路径数组分别代表七种不同的方块组合及空方块
var nextBlockImagePath = [];
nextBlockImagePath[NOTHING] = "image/nextnothing.jpg";
nextBlockImagePath[SQUARE] = "image/nextblock0.jpg";
nextBlockImagePath[BLOCKS_1] = "image/nextblock1.jpg";
nextBlockImagePath[BLOCKS_2] = "image/nextblock2.jpg";
nextBlockImagePath[BLOCKS_3] = "image/nextblock3.jpg";
nextBlockImagePath[BLOCKS_4] = "image/nextblock4.jpg";
nextBlockImagePath[BLOCKS_5] = "image/nextblock5.jpg";
nextBlockImagePath[LONG] = "image/nextblock6.jpg";

//记录方块的位图的数组(1D)
var squareImage = [];
//记录已经着地方块的类型的数组(2D)
var fellBlocks = [];
////记录修改前的已经着地方块的类型的数组(2D)
//var fellBlocksBeforeModify = [];
//记录已经着地方块的图形的容器的数组(2D)
fellBlocksDiv = [];
//记录再下一个方块组合的图形
var nextImage;
//记录再下一个再下一个方块组合的图形
var nextAndNextImage;


//初始化方块的位图的数组
for (type = 0; type < TYPE_COUNT; type ++)
{
	image = document.createElement("img");
	image.src = squareImagePath[type];
	squareImage[type] = image;
}

//初始化已经着地方块的图形的容器
for (i = 0; i < HORIZONTAL_COUNT; i ++)
{
	//变为二维数组
	fellBlocks[i] = [];
//	fellBlocksBeforeModify[i] = [];
	fellBlocksDiv[i] = [];
	for (j = 0; j < VERTICAL_COUNT; j ++)
	{	
		fellBlocks[i][j] = NOTHING;
//		fellBlocksBeforeModify[i][j] = NOTHING;
		
		//新建DIV元素
		div = document.createElement("div");
		//通过style属性对容器进行定位
		div.style.position = "absolute";
		div.style.left = i * SQUARE_SIZE + X_OFFSET;
		div.style.top = j * SQUARE_SIZE + Y_OFFSET;
		div.style.zIndex = HIGH_Z_INDEX;
		//把容器记录到二维数组
		fellBlocksDiv[i][j] = div;
		document.getElementById("BackGroundArea").appendChild(div);
		
		//复制图像元素
		image = squareImage[NOTHING].cloneNode(true);
		//把图像添加到对应的容器
		div.appendChild(image);

	}
}


//初始化下一个方块组合的图形
image = document.createElement("img");
image.src = nextBlockImagePath[NOTHING];
image.style.position = "absolute";
image.style.left = X_OFFSET_NEXT;
image.style.top = Y_OFFSET_NEXT;
image.style.zIndex = 10;
nextImage = image;
document.getElementById("BackGroundArea").appendChild(image);

//初始化下一个再下一个方块组合的图形
image = document.createElement("img");
image.src = nextBlockImagePath[NOTHING];
image.style.position = "absolute";
image.style.left = X_OFFSET_NEXT_NEXT;
image.style.top = Y_OFFSET_NEXT_NEXT;
image.style.zIndex = 10;
nextAndNextImage = image;
document.getElementById("BackGroundArea").appendChild(image);

image.src = squareImagePath[NOTHING];
div.style.zIndex = HIGH_Z_INDEX;

2.初始化新的方块组合,并处理方块组合
//定义类FallingBlocks
function FallingBlocks()
{
	//方块组合的方向
	this.direction;
	this.directionCount = 0;
	//方块组合横、纵坐标数组(每个方块组合组由4 个方块组成)
	this.x = [];
	this.y = [];
	//方块组合的重心的横、纵坐标
	this.xOfHeart;
	this.yOfHeart;
	//方块组合下落一格后的横、纵坐标数组(每个方块组合组由4 个方块组成)
	this.xPos = [];
	this.yPos = [];
	//方块组合下落一格后的重心的横、纵坐标
	this.xPosOfHeart;
	this.yPosOfHeart;
	
	//方块组合的类型(7种方块组合和空方块)
	this.type;
	//下一个方块组合的类型
	temp = Math.random() * 6;
	this.typeOfNext = Math.floor(temp);
	//下一个再下一个方块组合的类型
	temp = Math.random() * 6;
	this.typeOfNextAndNext = Math.floor(temp);

	//初始化新的方块组合,并把它放在最顶的位置
	this.initFallingBlocks;
	//根据方块组合的类型,及其重心的位置,测试它的形状(即计算各个方块的位置)
	this.testBlocksShape;
	//把完成测试的形状记录到方块组合的位置坐标
	this.saveBlocksShape;
	//设定SQUARE
	this.setSquare;
	//设定LONG
	this.setLong;
	//设定BLOCKS_1
	this.setBlocks1;
	//设定BLOCKS_2
	this.setBlocks2;
	//设定BLOCKS_3
	this.setBlocks3;
	//设定BLOCKS_4
	this.setBlocks4;
	//设定BLOCKS_5
	this.setBlocks5;
	//检查方块的坐标是否超出范围
	this.isOut;
	//绘制正在下落的方块组合
	this.paintFallingBlocks;
	//处理着地的方块组合
	this.processFellBlocks;
}

//初始化新的方块组合,并把它放在最顶的位置
FallingBlocks.prototype.initFallingBlocks = function()
{
	//获得当前方块组合的类型
	this.type = this.typeOfNext;
	//获得下一个方块组合的类型
	this.typeOfNext = this.typeOfNextAndNext;
	//设定下一个再下一个方块组合的类型
	temp = Math.random() * 6;
	this.typeOfNextAndNext = Math.floor(temp);
	//每30个方块组合,出现一次长条
	this.directionCount ++;
	if (this.directionCount % 30 == 0)
	{
		this.typeOfNextAndNext = LONG;
	}
	//设定方块组合的重心的初始横、纵坐标
	this.xPosOfHeart = INIT_HORIZONTAL_POS;
	this.yPosOfHeart = INIT_VERTICAL_POS;
	//重新把方块组合的方向变为0
	this.direction = 0;
	//若测试的形状符合要求,则记录方块组合的形状
	if (this.testBlocksShape())
	{
		this.saveBlocksShape();
		//绘制正在下落的方块组合
		this.paintFallingBlocks();
	}
}


//根据方块组合的类型,及其重心的位置,测试它的形状(即计算各个方块的位置)
FallingBlocks.prototype.testBlocksShape = function()
{
	//对方块组合的类型分类处理
	switch (this.type)
	{
	case SQUARE:
		this.setSquare();
		break;
	case LONG:
		this.setLong();
		break;
	case BLOCKS_1:
		this.setBlocks1();
		break;
	case BLOCKS_2:
		this.setBlocks2();
		break;
	case BLOCKS_3:
		this.setBlocks3();
		break;
	case BLOCKS_4:
		this.setBlocks4();
		break;
	case BLOCKS_5:
		this.setBlocks5();
		break;
	}
	//测试新的形状是否符合要求
	for (var i = 0; i < BLOCKS_SIZE; i ++)
	{
		//若第i 个方块的坐标超出范围
		if (this.isOut(this.xPos[i], this.yPos[i]))
		{
			return false;
		}
		//若第i 个方块的坐标有已经着地的方块
		if (tetris.fellBlocks[this.xPos[i]][this.yPos[i]] != NOTHING )
		{
			return false;
		}
	}
	return true;
}


//把完成测试的形状记录到方块组合的位置坐标
FallingBlocks.prototype.saveBlocksShape = function()
{
	this.xOfHeart = this.xPosOfHeart;
	this.yOfHeart = this.yPosOfHeart;
	for (var i = 0; i < BLOCKS_SIZE; i ++)
	{
		this.x[i] = this.xPos[i];
		this.y[i] = this.yPos[i];
	}
}

//设定SQUARE
FallingBlocks.prototype.setSquare = function()
{
	switch (this.direction)
	{
	//4个方向都一样
	case 0:
	case 1:
	case 2:
	case 3:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart + 1;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	}
}


//设定LONG
FallingBlocks.prototype.setLong = function()
{
	switch (this.direction)
	{
	//两个方向都一样
	case 0:
	case 2:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart + 2;
		this.yPos[3] = this.yPosOfHeart;
		break;
	//两个方向都一样
	case 1:
	case 3:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart + 2;
		break;
	}
}

//设定BLOCKS_1
FallingBlocks.prototype.setBlocks1 = function()
{
	switch (this.direction)
	{
	case 0:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart - 1;
		break;
	case 1:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart;
		break;
	case 2:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 3:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart;
		break;
	}
}


//设定BLOCKS_2
FallingBlocks.prototype.setBlocks2 = function()
{
	switch (this.direction)
	{
	//两个方向都一样
	case 0:
	case 2:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	//两个方向都一样
	case 1:
	case 3:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart - 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	}
}


//设定BLOCKS_3
FallingBlocks.prototype.setBlocks3 = function()
{
	switch (this.direction)
	{
	//两个方向都一样
	case 0:
	case 2:
		this.xPos[0] = this.xPosOfHeart + 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	//两个方向都一样
	case 1:
	case 3:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart - 1;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	}
}


//设定BLOCKS_4
FallingBlocks.prototype.setBlocks4 = function()
{
	switch (this.direction)
	{
	case 0:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart - 1;
		this.yPos[1] = this.yPosOfHeart + 1;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 1:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart - 1;
		this.yPos[1] = this.yPosOfHeart - 1;
		this.xPos[2] = this.xPosOfHeart - 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 2:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 3:
		this.xPos[0] = this.xPosOfHeart + 1;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart + 1;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	}
}


//设定BLOCKS_5
FallingBlocks.prototype.setBlocks5 = function()
{
	switch (this.direction)
	{
	case 0:
		this.xPos[0] = this.xPosOfHeart + 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart + 1;
		this.yPos[1] = this.yPosOfHeart + 1;
		this.xPos[2] = this.xPosOfHeart;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 1:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart - 1;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart - 1;
		this.yPos[2] = this.yPosOfHeart + 1;
		this.xPos[3] = this.xPosOfHeart;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 2:
		this.xPos[0] = this.xPosOfHeart - 1;
		this.yPos[0] = this.yPosOfHeart;
		this.xPos[1] = this.xPosOfHeart;
		this.yPos[1] = this.yPosOfHeart;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart - 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	case 3:
		this.xPos[0] = this.xPosOfHeart;
		this.yPos[0] = this.yPosOfHeart - 1;
		this.xPos[1] = this.xPosOfHeart + 1;
		this.yPos[1] = this.yPosOfHeart - 1;
		this.xPos[2] = this.xPosOfHeart + 1;
		this.yPos[2] = this.yPosOfHeart;
		this.xPos[3] = this.xPosOfHeart + 1;
		this.yPos[3] = this.yPosOfHeart + 1;
		break;
	}
}


//检查方块的坐标是否超出范围
FallingBlocks.prototype.isOut = function(x, y)
{
	if (x < 0 || x >= HORIZONTAL_COUNT)
	{
		return true;
	}
	if (y >= VERTICAL_COUNT)
	{
		return true;
	}
	return false;
}


//绘制正在下落的方块组合(被Tetris调用的方法)
FallingBlocks.prototype.paintFallingBlocks = function()
{
	//清空之前的
	for (var i = 0; i < BLOCKS_SIZE; i ++)
	{
		//暂存对应的DIV
		div = fellBlocksDiv[this.x[i]][this.y[i]];
		//旧的图像元素
		oldImage = div.firstChild;
		//新的图像元素
		newImage = squareImage[NOTHING].cloneNode(true);
		//替换图像元素
		div.replaceChild(newImage, oldImage);
	}
	//绘制当前的
	for (var i = 0; i < BLOCKS_SIZE; i ++)
	{
		//暂存对应的DIV
		div = fellBlocksDiv[this.xPos[i]][this.yPos[i]];
		//旧的图像元素
		oldImage = div.firstChild;
		//新的图像元素
		newImage = squareImage[this.type].cloneNode(true);
		//替换图像元素
		div.replaceChild(newImage, oldImage);
	}
}


//处理着地的方块组合(被Tetris调用的方法)
FallingBlocks.prototype.processFellBlocks = function()
{
	//计算方块组合最低的位置和最高的位置
	tetris.lowest = INIT_VERTICAL_POS;
	//记录方块组合到已经着地方块
	for (var i = 0; i < BLOCKS_SIZE; i ++)
	{
		tetris.fellBlocks[this.x[i]][this.y[i]] = this.type;
		//修改最低的位置(lowest越大,位置越低)
		if (tetris.lowest < this.y[i])
		{
			tetris.lowest = this.y[i];
		}
	}
	
	//遍历所有已经着地方块
	findHighest:
	for (j = 0; j < VERTICAL_COUNT; j ++)
	{
		for (i = 0; i < HORIZONTAL_COUNT; i ++)
		{
			//找到已经着地方块的最高位置
			if (tetris.fellBlocks[i][j] != NOTHING)
			{
				tetris.highest = j;
				break findHighest;
			}
		}
	}
	//如果最低的位置已经在垂直方向的出发点,则认为游戏已经结束
	if (tetris.lowest <= INIT_VERTICAL_POS)
	{
		tetris.isLose = true;
		return;
	}

	nextRow:
	//搜索消减方块(从最低位置的那行遍历到垂直方向出发点的下面一行)
	for (var j = tetris.lowest; j > INIT_VERTICAL_POS; )
	{
		//假设这行全部是空
		isAllEmpty = true;
		//假设这行全部是满
		isAllFull = true;
		//遍历每一行
		for (var i = 0; i < HORIZONTAL_COUNT; i ++)
		{
			//若这格是空
			if (tetris.fellBlocks[i][j] == NOTHING)
			{
				isAllFull = false;
			}
			//若这格是满
			else
			{
				isAllEmpty = false;
			}
			//若已经不是全满且已经不是全空
			if (! isAllFull && ! isAllEmpty)
			{
				//搜索上面的一行
				j --;
				continue nextRow;
			}
		}
		//若这行全部是满,删除这一行
		if (isAllFull)
		{
			for (var jMove = j; jMove > INIT_VERTICAL_POS; jMove --)
			{
				for (var iMove = 0; iMove < HORIZONTAL_COUNT; iMove ++)
				{
					//向下移动一格
					tetris.fellBlocks[iMove][jMove] = 
						tetris.fellBlocks[iMove][jMove - 1];
				}
			}
			//继续遍历这一行
			continue;
		}
		//若这行全部是空,完成消减方块,退出循环
		if (isAllEmpty)
		{
			break;
		}
	}

	//检查游戏是否结束
	for (var i = 0; i < HORIZONTAL_COUNT; i ++)
	{
		//若在第二行有一个格不是空
		if (tetris.fellBlocks[i][INIT_VERTICAL_POS] != NOTHING)
		{
			tetris.isLose = true;
			break;
		}
	}
	this.initFallingBlocks();
}

3.键盘监听,及方块组合的形状规律
//定义类Tetris
function Tetris()
{
	//已经着地方块的类型的数组
	this.fellBlocks = fellBlocks;
	//定义正在下落的方块组合
	this.fallingBlocks;
	//游戏是否结束的旗标
	this.isLose = false;

	//处理按下键盘的函数
	this.keyPressed;
	//定义每1 秒执行一次的事件监听器
	this.timer;
	//总的初始化的方法
	this.init;
	//用于重绘图象的方法
	this.repaint;
	//绘制已经着地方块
	this.paintFellBlocks;
	//定义所有方块最高的位置
	this.highest;
	//定义方块组合最低的位置
	this.lowest;
}

//定义键盘监听的函数
Tetris.prototype.keyPressed = function(event)
{
	fallingBlocks = tetris.fallingBlocks;
	//兼容IE和Firefox
	if (event == null)
	{
		curKey = window.event.keyCode;
	}
	else
	{
		curKey = event.charCode;
	}
	switch (curKey)
	{
	//按下向左键或A键时,方块向左移动一格
	case 97:
	case 65:
		//测试的横坐标减1
		fallingBlocks.xPosOfHeart --;
		//若测试的形状符合要求,则记录方块组合的形状
		if (fallingBlocks.testBlocksShape())
		{
			//绘制正在下落的方块组合
			fallingBlocks.paintFallingBlocks();
			fallingBlocks.saveBlocksShape();
		}
		//否则还原横坐标
		else
		{
			fallingBlocks.xPosOfHeart ++;
		}
		break;
	//按下向右键或D键时,方块向右移动一格
	case 100:
	case 68:
		//测试的横坐标加1
		fallingBlocks.xPosOfHeart ++;
		//若测试的形状符合要求,则记录方块组合的形状
		if (fallingBlocks.testBlocksShape())
		{
			//绘制正在下落的方块组合
			fallingBlocks.paintFallingBlocks();
			fallingBlocks.saveBlocksShape();
		}
		//否则还原横坐标
		else
		{
			fallingBlocks.xPosOfHeart --;
		}
		break;
	//按下向上键或W键时,方块向下移动一格
	case 119:
	case 87:
		//测试的纵坐标加1
		fallingBlocks.yPosOfHeart ++;
		//若测试的形状符合要求,则记录方块组合的形状
		if (fallingBlocks.testBlocksShape())
		{
			//绘制正在下落的方块组合
			fallingBlocks.paintFallingBlocks();
			fallingBlocks.saveBlocksShape();
		}
		//否则还原纵坐标
		else
		{
			fallingBlocks.yPosOfHeart --;
		}
		break;
	//按下向下键或D键时,方块向下移动到尽头
	case 115:
	case 83:
		while (true)
		{
			//测试的纵坐标加1
			fallingBlocks.yPosOfHeart ++;
			//若测试的形状符合要求,则记录方块组合的形状
			if (fallingBlocks.testBlocksShape())
			{
				//绘制正在下落的方块组合
				fallingBlocks.paintFallingBlocks();
				fallingBlocks.saveBlocksShape();
			}
			//否则还原纵坐标,处理着地的方块组合
			else
			{
				fallingBlocks.yPosOfHeart --;
				fallingBlocks.processFellBlocks();
				tetris.repaint();
				//跳出循环,终止向下移动
				break;
			}
		}
		break;
	//按下小键盘1键或J键时,方块向顺时针转动
	case 106:
	case 74:
		//测试的方向加1
		fallingBlocks.direction = 
			(fallingBlocks.direction + 1) % 4;
		//若测试的形状符合要求,则记录方块组合的形状
		if (fallingBlocks.testBlocksShape())
		{
			//绘制正在下落的方块组合
			fallingBlocks.paintFallingBlocks();
			fallingBlocks.saveBlocksShape();
		}
		//否则还原方向
		else
		{
			fallingBlocks.direction = 
			(fallingBlocks.direction - 1 + 4) % 4;
		}
		break;
	//按下小键盘2键或K键时,方块向逆时针转动
	case 107:
	case 75:
		//测试的方向减1
		fallingBlocks.direction = 
		(fallingBlocks.direction - 1 + 4) % 4;
		//若测试的形状符合要求,则记录方块组合的形状
		if (fallingBlocks.testBlocksShape())
		{
			//绘制正在下落的方块组合
			fallingBlocks.paintFallingBlocks();
			fallingBlocks.saveBlocksShape();
		}
		//否则还原方向
		else
		{
			fallingBlocks.direction = 
			(fallingBlocks.direction + 1) % 4;
		}
		break;
	}
}



//定义每1 秒执行一次的事件监听器
Tetris.prototype.timer = function()
{
	//测试的纵坐标加1
	this.fallingBlocks.yPosOfHeart ++;
	//若测试的形状符合要求,则记录方块组合的形状
	if (this.fallingBlocks.testBlocksShape())
	{
		//绘制正在下落的方块组合
		this.fallingBlocks.paintFallingBlocks();
		this.fallingBlocks.saveBlocksShape();
	}
	//否则还原纵坐标,处理着地的方块组合
	else
	{
		this.fallingBlocks.yPosOfHeart --;
		this.fallingBlocks.processFellBlocks();
		tetris.repaint();
	}

	//如果游戏还没有结束
	if (this.isLose != true)
	{
		//0.8秒后激发一次计时器
		temp = this.timer;
		setTimeout("tetris.timer();" , 800);
	}
}


//总的初始化的方法
Tetris.prototype.init = function() 
{
	//创建FallingBlocks的实例,并初始化
	this.fallingBlocks = new FallingBlocks();
	this.fallingBlocks.initFallingBlocks();
	//开始计时器
	this.timer();
	//注册键盘监听的函数
	document.onkeypress = this.keyPressed;
}


//用于重绘图象的方法
Tetris.prototype.repaint = function()
{
//	//绘制背景
//	document.getElementById("BackGroundImage").src = "image/background.jpg";
	//绘制下一个方块组合
	nextImage.src = nextBlockImagePath[this.fallingBlocks.typeOfNext];
	//绘制下一个再下一个方块组合
	nextAndNextImage.src = nextBlockImagePath[this.fallingBlocks.typeOfNextAndNext];
	//绘制已经着地方块
	this.paintFellBlocks();
	//如果游戏已经结束
	if (this.isLose)
	{
		alert("游戏结束!");
	}
}

//绘制已经着地方块
Tetris.prototype.paintFellBlocks = function()
{
	//遍历最高行到最低行的已经着地方块的类型
	for (var j = this.highest; j <= this.lowest; j ++)
	{
		for (var i = 0; i < HORIZONTAL_COUNT; i ++)
		{
			newType = this.fellBlocks[i][j];
			//暂存对应的DIV
			div = fellBlocksDiv[i][j];
			//旧的图像元素
			oldImage = div.firstChild;
			//新的图像元素
			newImage = squareImage[newType].cloneNode(true);
			//替换图像元素
			div.replaceChild(newImage, oldImage);
		}
	}
}

4.方块游戏的启动
//创建Tetris的对象
var tetris = new Tetris();
tetris.init();

5.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>JavaScript俄罗斯方块</title>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
</head>

<body>
<div id="BackGroundArea">
			<img id="BackGroundImage" src="image/background.jpg"
			style="position:absolute; left:0; top: 0; z-index:5"></img>
		</div>
		<div id="ReadMe" 
		style="position:absolute; left:0; top: 343; z-index:10">
			JavaScript俄罗斯方块
			<br/>
            操作说明:
			<br/>
			向左移一格:A
			<br/>
			向右移一格:D
			<br/>
			向下移一格:W
			<br/>
			向下到底:S
			<br/>
			顺时针转动:J
			<br/>
			逆时针转动:K
		</div>
	</body>
	<script language="JavaScript" src="init.js"></script>
	<script language="JavaScript" src="fallingblocks.js"></script>
	<script language="JavaScript" src="tetris.js"></script>
	<script language="JavaScript" src="run.js"></script>
</body>
</html>
0
0
分享到:
评论

相关推荐

    python基于pygame的俄罗斯方块小游戏源码.zip

    python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。...

    俄罗斯方块(C语言版) 俄罗斯方块

    【俄罗斯方块(C语言版) 俄罗斯方块】是一个基于C语言实现的经典游戏项目,它将编程技术与游戏设计巧妙结合,展示了C语言在创建交互式程序方面的潜力。在这个项目中,开发者利用C语言的基本结构,如循环、条件语句...

    java毕业设计——俄罗斯方块项目(论文+答辩PPT+源代码+数据库+讲解视频).zip

    java毕业设计——俄罗斯方块项目(论文+答辩PPT+源代码+数据库+讲解视频).zip java毕业设计——俄罗斯方块项目(论文+答辩PPT+源代码+数据库+讲解视频).zip java毕业设计——俄罗斯方块项目(论文+答辩PPT+源代码+...

    俄罗斯方块C语言报告

    ### 俄罗斯方块C语言程序设计报告 #### 一、问题描述 俄罗斯方块(俄文:Тетрис)是一款经典的益智类游戏,最初由苏联程序员阿列克谢·帕基特诺夫于1984年开发。游戏的目标是通过移动、旋转屏幕上的方块,...

    俄罗斯方块C++源代码

    《俄罗斯方块C++源代码解析》 在编程领域,经典游戏俄罗斯方块是一个极好的学习案例,它涉及到了基础的图形界面设计、事件处理、数据结构和算法等多个知识点。本篇文章将对“俄罗斯方块C++源代码”进行深入剖析,...

    VC可视化俄罗斯方块源码

    俄罗斯方块是我大学一年级刚学VC++时的课程设计,当时的课程设计有三种,单文档、多文档和俄罗斯方块。我选择俄罗斯方块,就是因为它是游戏。 之前我是玩过俄罗斯方块的,一种是单人的(单人版),一种是两人对战的...

    俄罗斯方块游戏-JAVA实现(含双人联机对战).zip

    俄罗斯方块游戏--JAVA实现(含双人联机对战).zip 俄罗斯方块游戏--JAVA实现(含双人联机对战).zip 俄罗斯方块游戏--JAVA实现(含双人联机对战).zip 俄罗斯方块游戏--JAVA实现(含双人联机对战).zip 俄罗斯方块...

    c语言俄罗斯方块完整源码

    c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言俄罗斯方块完整源码 c语言...

    MFC编写的俄罗斯方块

    《MFC编写的俄罗斯方块》是一款利用Microsoft Foundation Classes (MFC)库开发的经典小游戏,它结合了声音效果和用户友好的图形界面,为玩家提供了一种沉浸式的游戏体验。MFC是微软提供的一个C++类库,它使得开发者...

    flash俄罗斯方块源代码

    《深入解析Flash俄罗斯方块源代码》 在游戏开发领域,经典的俄罗斯方块以其独特的玩法和无尽的挑战性,始终吸引着众多开发者去实现。本篇将详细探讨一款使用Flash技术编写的俄罗斯方块源代码,帮助你理解并学习...

    Python课程设计之俄罗斯方块

    在本项目中,"Python课程设计之俄罗斯方块"是一个基于Python编程语言实现的经典游戏——俄罗斯方块。这个课程设计旨在帮助学生理解Python的基本语法、控制结构、对象导向编程以及图形用户界面(GUI)的创建。以下是...

    俄罗斯方块-微信小游戏-项目源码

    这是一个微信小游戏项目源码,是经典怀旧的俄罗斯方块游戏,适合新手入门参考学习,下面还有↓ 使用微信开发工具选择小游戏导入即可打开,可编译运行,请放心下载, 相关指导教程请看作者发表的以下文章: ① 微信...

    verilog设计俄罗斯方块_俄罗斯方块_VHDL-FPGA-Verilog_

    《基于FPGA的Verilog实现俄罗斯方块游戏详解》 在现代数字系统设计中,FPGA(Field-Programmable Gate Array)因其可重构性和高速处理能力被广泛应用。结合高级硬件描述语言如Verilog,我们可以实现复杂的功能,...

    C#俄罗斯方块(多国语言完美版)

    《C#实现的多国语言俄罗斯方块游戏详解》 在编程领域,C#是一种广泛应用于桌面应用开发、游戏开发和Web服务的编程语言。它以其高效性、易读性和强大的.NET框架支持而受到开发者们的青睐。本项目“C#俄罗斯方块(多国...

    俄罗斯方块物理版[含源码]

    《俄罗斯方块物理版》是一款基于Box2D引擎和OpenGL渲染技术实现的创新性游戏,由C++编程语言精心打造。这款项目展示了如何将经典的电子游戏与物理学相结合,为玩家带来更为真实的游戏体验。下面我们将深入探讨这个...

    Java俄罗斯方块源代码,Java俄罗斯方块源代码

    Java语言实现的俄罗斯方块是一款经典的桌面游戏,它利用了编程的基本概念,如循环、条件判断、对象和类,以及图形用户界面(GUI)的设计。在这个项目中,开发者需要理解以下核心知识点: 1. **Java基础**:Java是...

    俄罗斯方块(C#源码+音效)

    【标题】:“俄罗斯方块(C#源码+音效)” 这个项目是基于C#编程语言实现的经典游戏——俄罗斯方块。C#是一种面向对象的、类型安全的、组件导向的语言,由微软公司开发,广泛应用于Windows平台的软件开发,尤其是...

    LABVIEW做的俄罗斯方块

    《使用LABVIEW构建的俄罗斯方块游戏详解》 在编程世界中,各种工具和语言都有其独特的魅力和应用领域。其中,LABVIEW(Laboratory Virtual Instrument Engineering Workbench)以其图形化编程界面和强大的数据处理...

    C#俄罗斯方块(winform)

    C#俄罗斯方块(winform)C#俄罗斯方块(winform)C#俄罗斯方块(winform)C#俄罗斯方块(winform)C#俄罗斯方块(winform)C#俄罗斯方块(winform)C#俄罗斯方块(winform)

    tetris俄罗斯方块cocoscreator源码

    《 Tetris俄罗斯方块CocosCreator源码解析与技术探讨》 Tetris,即我们熟知的俄罗斯方块,是一款经典的益智游戏,其简洁的规则和无尽的挑战性吸引了全球无数玩家。CocosCreator是一款强大的2D游戏开发引擎,结合了...

Global site tag (gtag.js) - Google Analytics