JS-2048游戏

#根据慕课网教导尝试做的一个2048小游戏

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>2048</title>
		<link rel="stylesheet" type="text/css" href="2048.css" />
		<script src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="main2048.js" type="text/javascript" charset="utf-8"></script>
		<script src="showanimation2048.js" type="text/javascript" charset="utf-8"></script>
		<script src="support2048.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<header>
			<h1>2048</h1>
			<a href="javascript:newgame();" id="newgamebutton">New Game</a>
			<p>score:<span id="score">0</span></p>
		</header>
		<div id="grid-container">
			<div class="grid-cell" id="grid-cell-0-0"></div>
			<div class="grid-cell" id="grid-cell-0-1"></div>
			<div class="grid-cell" id="grid-cell-0-2"></div>
			<div class="grid-cell" id="grid-cell-0-3"></div>

			<div class="grid-cell" id="grid-cell-1-0"></div>
			<div class="grid-cell" id="grid-cell-1-1"></div>
			<div class="grid-cell" id="grid-cell-1-2"></div>
			<div class="grid-cell" id="grid-cell-1-3"></div>

			<div class="grid-cell" id="grid-cell-2-0"></div>
			<div class="grid-cell" id="grid-cell-2-1"></div>
			<div class="grid-cell" id="grid-cell-2-2"></div>
			<div class="grid-cell" id="grid-cell-2-3"></div>

			<div class="grid-cell" id="grid-cell-3-0"></div>
			<div class="grid-cell" id="grid-cell-3-1"></div>
			<div class="grid-cell" id="grid-cell-3-2"></div>
			<div class="grid-cell" id="grid-cell-3-3"></div>
		</div>
	</body>
</html>

header {
	display: block;
	margin: 0 auto;
	width: 500px;
	text-align: center;
}

header h1 {
	font-family: arial;
	font-size: 60px;
	font-weight: bold;
}

header #newgamebutton {
	margin: 20 auto;
	width: 100px;
	padding: 10px;
	background-color: #8f7a66;
	font-family: arial;
	color: #fff;
	border-radius: 10px;
	text-decoration: none;
}

header #newgamebutton:hover {
	background-color: #9f8b77;
}

header p {
	font-family: arial;
	font-size: 25px;
	margin: 20px auto;
}

#grid-container {
	width: 460px;
	height: 460px;
	padding: 20px;
	margin: 50px auto;
	background-color: #bbada0;
	border-radius: 10px;
	position: relative;
}

.grid-cell {
	width: 100px;
	height: 100px;
	border-radius: 6px;
	background-color: #ccc0b3;
	position: absolute;
}

.number-cell {
	font-family: arial;
	font-size: 20px;
	font-weight: bold;
	line-height: 100px;
	text-align: center;
	border-radius: 6px;
	position: absolute;
}

// 游戏主逻辑
var board = new Array();
var score = 0;
var hasConflicted = new Array();

$(document).ready(function() {
	newgame();
});

function newgame() {
	// 初始化棋盘格
	init();
	// 在随机两个格子生成数字
	generateOneNumber();
	generateOneNumber();
}

function init() {
	for (var i = 0; i < 4; i++)
		for (var j = 0; j < 4; j++) {
			var gridCell = $("#grid-cell-" + i + "-" + j);
			gridCell.css('top', getPosTop(i, j));
			gridCell.css('left', getPosLeft(i, j));
		}

	for (var i = 0; i < 4; i++) {
		board[i] = new Array();
		hasConflicted[i] = new Array();
		for (var j = 0; j < 4; j++) {
			board[i][j] = 0;
			hasConflicted[i][j] = false;
		}
	}
	// 根据board值进行操作
	updateBoardView();
	// 分数初始化
	score = 0;
}

function updateBoardView() {
	// 如果有.number-cell将其移除
	$(".number-cell").remove();
	for (var i = 0; i < 4; i++)
		for (var j = 0; j < 4; j++) {
			$("#grid-container").append('<div class="number-cell" id="number-cell-' + i + '-' + j + '"></div>');
			var theNumberCell = $("#number-cell-" + i + "-" + j);
			if (board[i][j] == 0) {
				theNumberCell.css('width', '0px');
				theNumberCell.css('heigth', '0px');
				theNumberCell.css('top', getPosTop(i, j) + 50);
				theNumberCell.css('left', getPosLeft(i, j) + 50);
			} else {
				theNumberCell.css('width', '100px');
				theNumberCell.css('heigth', '100px');
				theNumberCell.css('top', getPosTop(i, j));
				theNumberCell.css('left', getPosLeft(i, j));
				theNumberCell.css('background-color', getNumberBackgroundColor(board[i][j]));
				theNumberCell.css('color', getNumberColor(board[i][j]));
				theNumberCell.text(board[i][j]);
			}

			hasConflicted[i][j] = false;
		}

}

function generateOneNumber() {
	if (nospace(board))
		return false;

	// 随机一个位置
	var randx = parseInt(Math.floor(Math.random() * 4));
	var randy = parseInt(Math.floor(Math.random() * 4));
	var times = 0;
	while (times < 50) {
		if (board[randx][randy] == 0)
			break;
		randx = parseInt(Math.floor(Math.random() * 4));
		randy = parseInt(Math.floor(Math.random() * 4));

		times++;
	}
	if (times == 50) {
		for (var i = 0; i < 4; i++)
			for (var j = 0; j < 4; j++) {
				if (board[i][j] == 0) {
					randx = i;
					randy = j;
				}
			}
	}
	// 随机一个数字
	var randNumber = Math.random() < 0.5 ? 2 : 4;
	// 在随机位置显示出随机数字
	board[randx][randy] = randNumber;
	showNumberWithAnimation(randx, randy, randNumber);

	return true;
}
$(document).keydown(function(event) {
	switch (event.keyCode) {
		case 37: //left
			if (moveLeft()) {
				setTimeout("generateOneNumber()", 210);
				setTimeout("isgameover()", 300);
			}
			break;
		case 38: //up
			if (moveUp()) {
				setTimeout("generateOneNumber()", 210);
				setTimeout("isgameover()", 300);
			}
			break;
		case 39: //right
			if (moveRight()) {
				setTimeout("generateOneNumber()", 210);
				setTimeout("isgameover()", 300);
			}
			break;
		case 40: //down
			if (moveDown()) {
				setTimeout("generateOneNumber()", 210);
				setTimeout("isgameover()", 300);
			}
			break;
		default: //defauit
			break;
	}
});

function isgameover() {
	if (nospace(board) && nomove(board)) {
		gameover();
	}

}

function gameover() {
	alert("gameover!")
}

function moveLeft() {
	// 判断canMoveLeft()
	// 1:左边是否没有数字
	// 2:左边数字是否和自己相等
	if (!canMoveLeft(board))
		return false;

	// movLeft
	// 1:落脚位置是否为空
	// 2:落脚位置数字和待判定元素位置相等i
	// 3:移动路径中是否有障碍物
	for (var i = 0; i < 4; i++)
		for (var j = 1; j < 4; j++) {
			if (board[i][j] != 0) {
				for (var k = 0; k < j; k++) {
					if (board[i][j] == 0 && noBlockHorizontal(i, k, j, board)) {
						// move
						showMoveAnimation(i, j, i, k);
						board[i][k] = board[i][j];	
						board[i][j] = 0;
						continue;
					} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
						// move
						showMoveAnimation(i, j, i, k);
						// add
						board[i][k] *= 2;
						board[i][j] = 0;
						// add score
						score += board[i][k];
						// 通知前台
						updateScore(score);
						hasConflicted[i][k] = true;
						continue;
					}
				}
			}
		}

	setTimeout("updateBoardView()", 200);
	return true;
}

function moveRight() {
	if (!canMoveRight(board))
		return false;

	for (var i = 0; i < 4; i++)
		for (var j = 2; j >= 0; j--) {
			if (board[i][j] != 0) {
				for (var k = 3; k > j; k--) {
					if (board[i][k] == 0 && noBlockHorizontal(i, j, k, board)) {
						// move
						showMoveAnimation(i, j, i, k);
						board[i][k] = board[i][j];
						board[i][j] = 0;
						continue;
					} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
						// move
						showMoveAnimation(i, j, i, k);
						// add
						board[i][k] *= 2;
						board[i][j] = 0;
						// add score
						score += board[i][k];
						// 通知前台
						updateScore(score);
						hasConflicted[i][k] = true;
						continue;
					}
				}
			}
		}

	setTimeout("updateBoardView()", 200);
	return true;
}

function moveUp() {
	if (!canMoveUp(board))
		return false;

	for (var j = 0; j < 4; j++)
		for (var i = 1; i < 4; i++) {
			if (board[i][j] != 0) {
				for (var k = 0; k < i; k++) {
					if (board[k][j] == 0 && noBlockVertical(j, k, i, board)) {
						// move
						showMoveAnimation(i, j, k, j);
						board[k][j] = board[i][j];
						board[i][j] = 0;
						continue;
					} else if (board[k][j] == board[i][j] && noBlockVertical(j, k, i, board) && !hasConflicted[k][j]) {
						// move
						showMoveAnimation(i, j, k, j);
						// add
						board[k][j] *= 2;
						board[i][j] = 0;
						// add score
						score += board[k][j];
						// 通知前台
						updateScore(score);
						hasConflicted[k][j] = true;
						continue;
					}
				}
			}
		}

	setTimeout("updateBoardView()", 200);
	return true;
}

function moveDown() {
	if (!canMoveDown(board))
		return false;

	for (var j = 0; j < 4; j++)
		for (var i = 2; i >= 0; i--) {
			if (board[i][j] != 0) {
				for (var k = 3; k > i; k--) {
					if (board[k][j] == 0 && noBlockVertical(j, i, k, board)) {
						// move
						showMoveAnimation(i, j, k, j);
						board[k][j] = board[i][j];
						board[i][j] = 0;
						continue;
					} else if (board[k][j] == board[i][j] && noBlockVertical(j, i, k, board) && !hasConflicted[k][j]) {
						// move
						showMoveAnimation(i, j, k, j);
						// add
						board[k][j] *= 2;
						board[i][j] = 0;
						// add score
						score += board[k][j];
						// 通知前台
						updateScore(score);
						hasConflicted[k][j] = true;
						continue;
					}
				}
			}
		}

	setTimeout("updateBoardView()", 200);
	return true;
}

// 动画效果逻辑
function showNumberWithAnimation(i, j, randNumber) {
	var numberCell = $("#number-cell-" + i + "-" + j);
	numberCell.css('background-color', getNumberBackgroundColor(randNumber));
	numberCell.css('color', getNumberColor(randNumber));
	numberCell.text(randNumber);
	numberCell.animate({
		width: "100px",
		height: "100px",
		top: getPosTop(i, j),
		left: getPosLeft(i, j)
	}, 50);
}

function showMoveAnimation(fromx, fromy, tox, toy) {
	var numberCell = $("#number-cell-" + fromx + "-" + fromy);
	numberCell.animate({
		top: getPosTop(tox, toy),
		left: getPosLeft(tox, toy)
	}, 200);
}

function updateScore(score) {
	$("#score").text(score);
}


// 底层逻辑
function getPosTop(i, j) {
	return 20 + i * 120
}

function getPosLeft(i, j) {
	return 20 + j * 120
}

function getNumberBackgroundColor(number) {
	switch (number) {
		case 2:
			return "#eee4da";
			break;
		case 4:
			return "#ede0c8";
			break;
		case 8:
			return "#f2b179";
			break;
		case 16:
			return "#f59563";
			break;
		case 32:
			return "#f67c5f";
			break;
		case 64:
			return "#f65e3b";
			break;
		case 128:
			return "#edcf72";
			break;
		case 256:
			return "#edcc61";
			break;
		case 512:
			return "#9c0";
			break;
		case 1024:
			return "#33b5e5";
			break;
		case 2048:
			return "#09c";
			break;
		case 4096:
			return "#a6c";
			break;
		case 8192:
			return "#93c";
			break;
	}
	return "black";
}

function getNumberColor(number) {
	if (number <= 4) {
		return "#776e65"
	}
	return "white";
}

function nospace(board) {
	for (var i = 0; i < 4; i++)
		for (var j = 0; j < 4; j++)
			if (board[i][j] == 0)
				return false;
	return true;
}
// moveLeft
function canMoveLeft(board) {
	for (var i = 0; i < 4; i++)
		for (var j = 1; j < 4; j++)
			if (board[i][j] != 0)
				if (board[i][j - 1] == 0 || board[i][j - 1] == board[i][j])
					return true;
	return false;
}

// moveRight
function canMoveRight(board) {
	for (var i = 0; i < 4; i++)
		for (var j = 2; j >= 0; j--)
			if (board[i][j] != 0)
				if (board[i][j + 1] == 0 || board[i][j + 1] == board[i][j])
					return true;
	return false;
}
// moveUp
function canMoveUp(board) {
	for (var j = 0; j < 4; j++)
		for (var i = 1; i < 4; i++)
			if (board[i][j] != 0)
				if (board[i - 1][j] == 0 || board[i - 1][j] == board[i][j])
					return true;
	return false;
}
// moveDown
function canMoveDown(board) {
	for (var j = 0; j < 4; j++)
		for (var i = 2; i >= 0; i--)
			if (board[i][j] != 0)
				if (board[i + 1][j] == 0 || board[i + 1][j] == board[i][j])
					return true;
	return false;
}
// left and right
function noBlockHorizontal(row, col1, col2, board) {
	for (var i = col1 + 1; i < col2; i++)
		if (board[row][i] != 0)
			return false;
	return true;
}
// up and down
function noBlockVertical(col, row1, row2, board) {
	for (var i = row1 + 1; i < row2; i++)
		if (board[i][col] != 0)
			return false;
	return true;
}

function nomove(board) {
	if (canMoveLeft(board) || canMoveRight(board) || canMoveUp(board) || canMoveDown(board))
		return false;
	return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值