JS實現的簡單俄羅斯方塊

寫了個簡單的俄羅斯方塊兒遊戲,算個筆記吧
關於在邊界的圖形轉換還存在一些問題,待優化。
在這裏插入圖片描述
在這裏插入圖片描述
HTML代碼

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>俄羅斯方塊</title>
		<script type="text/javascript" src="js/game.js"></script>
		
	</head>
	<body>
		<div id="maindiv" style="width: 800px;margin: 0 auto;">
			<span id="score" style="color: red;font-size: 18px;font-weight: bold;">您的分數爲:0</span>
		</div>
	</body>
</html>

JavaScript代碼

/*遊戲的寬度和高度*/
var TRTRIS_COLS = 16;
var TRTRIS_ROWS = 16;
var score = 0;
var timer1;

//定義全局方塊兒顏色
var colors = ['#F0F',"#F00","#0F0","#609","#CF0","#0FF"];

//定義一個存儲已經下落方塊位置的數組
var tetris_status = [];

for (var i = 0; i < TRTRIS_ROWS; i++) {
	tetris_status[i] = [];
	for (var j = 0; j < TRTRIS_COLS; j++) {
		tetris_status[i][j] = -1;
	}
}

//全局的table對象,以方便後期的函數處理
var Tries_table;

/*創建表格*/
var createTable = function(rows,cols,cellWidth,cellHeight){
	//DOM API
	var table = document.createElement('table');
	for (var i = 0; i < rows; i++) {
		var row = table.insertRow(i);
		for (var j = 0; j < cols; j++) {
			var cell = row.insertCell();
			cell.style.width = cellWidth+'px';
			cell.style.height = cellHeight+'px';
		}
	}
	return table;   //把創建的table對象返回
}

//定義一個下落方塊的座標值,當前下落的座標值
var blocks = [
	//Z方塊
	[
		{x:TRTRIS_COLS/2-1,y:0,color:0},
		{x:TRTRIS_COLS/2,y:0,color:0},
		{x:TRTRIS_COLS/2,y:1,color:0},
		{x:TRTRIS_COLS/2+1,y:1,color:0}
	],
	//田方塊
	[
		{x:TRTRIS_COLS/2,y:0,color:1},
		{x:TRTRIS_COLS/2+1,y:0,color:1},
		{x:TRTRIS_COLS/2,y:1,color:1},
		{x:TRTRIS_COLS/2+1,y:1,color:1},
	],
	//一方塊
	[
		{x:TRTRIS_COLS/2-1,y:0,color:2},
		{x:TRTRIS_COLS/2,y:0,color:2},
		{x:TRTRIS_COLS/2+1,y:0,color:2},
		{x:TRTRIS_COLS/2+2,y:0,color:2},
	],
	//右L方塊
	[
		{x:TRTRIS_COLS/2,y:0,color:3},
		{x:TRTRIS_COLS/2,y:1,color:3},
		{x:TRTRIS_COLS/2,y:2,color:3},
		{x:TRTRIS_COLS/2+1,y:2,color:3},
	],
	//左L方塊
	[
		{x:TRTRIS_COLS/2,y:0,color:4},
		{x:TRTRIS_COLS/2,y:1,color:4},
		{x:TRTRIS_COLS/2,y:2,color:4},
		{x:TRTRIS_COLS/2-1,y:2,color:4},
	],
	//T方塊
	[
		{x:TRTRIS_COLS/2-1,y:0,color:5},
		{x:TRTRIS_COLS/2,y:0,color:5},
		{x:TRTRIS_COLS/2+1,y:0,color:5},
		{x:TRTRIS_COLS/2,y:1,color:5},
	]
];

var currutBlock;

//初始化方塊兒
var initBlock = function(){
	var i = Math.floor(Math.random()*blocks.length);
	//var i = 2;
	currutBlock = [
		{x:blocks[i][0].x,y:blocks[i][0].y,color:blocks[i][0].color},
		{x:blocks[i][1].x,y:blocks[i][1].y,color:blocks[i][1].color},
		{x:blocks[i][2].x,y:blocks[i][2].y,color:blocks[i][2].color},
		{x:blocks[i][3].x,y:blocks[i][3].y,color:blocks[i][3].color},
	];
}

//頁面加載完成時再加載邏輯代碼
window.onload = function(){
	//創建table
	Tries_table = createTable(TRTRIS_ROWS,TRTRIS_COLS,16,16);
	//設置table屬性
	Tries_table.border = 1;
	Tries_table.style.borderCollapse = "collapse";
	Tries_table.style.margin = "0 auto";
	
	//把table放置到文檔中
	document.getElementById("maindiv").appendChild(Tries_table);
	
	//初始化新塊
	initBlock();
	
	//創建週期定時器
	timer1 = setInterval(fall,800);
}



//下落處理函數
var fall = function(){
	
	//遍歷下落中的每個方塊,是否能下落
	var canDown1 = true;
	var canDown2 = true;
	for (var i = 0; i < currutBlock.length; i++) {
		//判斷當前的y值是否觸底或者下方是否有方塊
		if(currutBlock[i].y >= (TRTRIS_ROWS-1)){
			canDown1 = false;
			break;
		}
		//判斷下落的方塊是否和已經存放的方塊有衝突
		if(tetris_status[currutBlock[i].y+1][currutBlock[i].x] != -1){
			canDown2 = false;
			break;
		}
	}
	
	if(canDown1 && canDown2){
		//把原來的位置變爲白色
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
		}
		//繪製下落方塊
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			blo.y++;
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
		}
	}else{
		//存儲方塊
		for (var i = 0; i < currutBlock.length; i++) {
			var cur = currutBlock[i];
			tetris_status[cur.y][cur.x] = cur.color;
		}
		
		initBlock();
		removeBlock();
		document.getElementById("score").innerText='您的分數爲:'+score;
	}
	
	//判斷遊戲是否結束
	var flag1 = false;
	for (var i = 0; i < TRTRIS_COLS; i++) {
		if(tetris_status[0][i] != -1) flag1 = true;
	}
	if(flag1){
		clearInterval(timer1);
		alert("Game Over");
		location.reload(true);
	}
}

//註冊事件,給整個窗體文檔註冊事件
window.onkeydown = function(e){
	switch(e.keyCode){
		//左移
		case 37:{
			moveLeft();
			break;
		}
		//右移
		case 39:{
			moveRight();
			break;
		}
		//下移
		case 40:{
			moveDown();
			break;
		}
		//旋轉
		case 38:{
			rotate();
			break;
		}
	}
}

//左移動處理
var moveLeft = function(){
	var canLeft = true;
	for (var i = 0; i < currutBlock.length; i++) {
		if(currutBlock[i].x < 1){
			canLeft = false;
			break;
		}
		//判斷左面是否有方塊
		if(tetris_status[currutBlock[i].y][currutBlock[i].x-1] != -1){
			canLeft = false;
			break;
		}
	}
	if(canLeft){
		//把原來的位置變爲白色
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
		}
		//左移方塊
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			blo.x--;
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
		}
	}
}

//右移動處理
var moveRight = function(){
	var canRight = true;
	for (var i = 0; i < currutBlock.length; i++) {
		if(currutBlock[i].x >= TRTRIS_COLS-1){
			canRight = false;
			break;
		}
		//判斷右面是否有方塊
		if(tetris_status[currutBlock[i].y][currutBlock[i].x+1] != -1){
			canRight = false;
			break;
		}
	}
	if(canRight){
		//把原來的位置變爲白色
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
		}
		//左移方塊
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			blo.x++;
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
		}
	}
}

//下移動處理
var moveDown = function(){
	var canDown1 = true;
	var canDown2 = true;
	for (var i = 0; i < currutBlock.length; i++) {
		//判斷當前的y值是否觸底或者下方是否有方塊
		if(currutBlock[i].y >= (TRTRIS_ROWS-1)){
			canDown1 = false;
			break;
		}
		//判斷下落的方塊是否和已經存放的方塊有衝突
		if(tetris_status[currutBlock[i].y+1][currutBlock[i].x] != -1){
			canDown2 = false;
			break;
		}
	}
	
	if(canDown1 && canDown2){
		//把原來的位置變爲白色
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
		}
		//左移方塊
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			blo.y++;
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
		}
	}
}

//旋轉方塊
var rotate = function(){
	var canRotate = true;
	//判斷能否旋轉
	for (var i = 0; i < currutBlock.length; i++) {
		var preX = currutBlock[i].x;
		var preY = currutBlock[i].y;
		if(i != 2){
			afterX = currutBlock[2].x + preY - currutBlock[2].y;
			afterY = currutBlock[2].y + currutBlock[2].x - preX;
			//是否超過左邊界
			if(afterX < 0 || tetris_status[afterY][afterX-1] != -1){
				canRotate = false;
				break;
			}
			//是否超過右邊界
			if(afterX >= TRTRIS_COLS-1 || tetris_status[afterY][afterX+1] != -1){
				canRotate = false;
				break;
			}
			//是否超過上邊界
			if(tetris_status[afterY+1][afterX] != -1 || afterY < 0){
				canRotate = false;
				break;
			}
			//是否超過下邊界
			if(afterY >= TRTRIS_ROWS-1 || tetris_status[afterY+1][afterX] != -1){
				canRotate = false;
				break;
			}
		}
	}	
	
	if(canRotate){
		//將原來的方塊變白
		for (var i = 0; i < currutBlock.length; i++) {
			Tries_table.rows[currutBlock[i].y].cells[currutBlock[i].x].style.backgroundColor = 'white';
		}
		//給旋轉完的方塊兒上色
		for (var i = 0; i < currutBlock.length; i++) {
			var preX = currutBlock[i].x;
			var preY = currutBlock[i].y;
			//定義一箇中心點,這個點爲下落方塊兒的旋轉中心
			if(i != 2){
				currutBlock[i].x = currutBlock[2].x + preY - currutBlock[2].y;
				currutBlock[i].y = currutBlock[2].y + currutBlock[2].x - preX;
			}
		}
		for (var i = 0; i < currutBlock.length; i++) {
			var blo = currutBlock[i];
			Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
		}
	}
}

//繪圖
var draw = function(){
	for (var m = 0; m < TRTRIS_ROWS; m++) {
		for (var n = 0; n < TRTRIS_COLS; n++) {
			if(tetris_status[m][n] != -1){
				Tries_table.rows[m].cells[n].style.backgroundColor = colors[tetris_status[m][n]];
			}else{
				Tries_table.rows[m].cells[n].style.backgroundColor = "white";
			}
		}
	}
}

//滿行消除
var removeBlock = function(){
	var flag = true;
	var theFull = [];
	for (var i = TRTRIS_ROWS-1; i >= 0; i--) {
		for (var j = 0; j < TRTRIS_COLS; j++) {
			if(tetris_status[i][j] == -1) {
				flag = false;
				break;
			}
		}
		if(flag) theFull[theFull.length] = i;
		
		/*if(flag){
			for (var k = 0; k < TRTRIS_COLS; k++) {
				tetris_status[i][k] = tetris_status[i-1][k];
			}
		}
		//draw();*/
		flag = true;
	}
	//解決多行同時消除問題
	//從上至下修改變量
	for (var i = theFull.length-1; i >=0 ; i--) {
		for (var l = theFull[i]; l > 0 ; l--) {
			for (var j = 0; j < TRTRIS_COLS; j++) {
				tetris_status[l][j] = tetris_status[l-1][j];
			}
		}
		
	}
	score += TRTRIS_COLS * theFull.length;
	draw();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章