<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网页版2048</title>
<style type="text/css">
#tblAll,#tblAll td {
	border: 1px solid blue;
	border-collapse: collapse;
}

#tblAll {
	width: 100%;
}

/*菜单所在容器*/
#divMenu {
	text-align: right;
	border: 1px solid green;
}

#gameName {
	font-size: 2em;
	font-weight: bold;
}

#tblScore,#tblScore td {
	border: 1px solid blue;
	border-collapse: collapse;
}

#tblScore {
	width: 100%;
	margin-bottom: 2em;
	table-layout: fixed;
}

.score {
	text-align: center;
	background-color: gray;
}

#tblBtns {
	width: 100%;
}

#tdRestart {
	width: 50%;
	text-align: left;
}

#tdUndo {
	width: 50%;
	text-align: right;
}

#tblGame {
	width: 100%;
	/*设置表格的单元格不会因为内容而改变大小*/
	table-layout: fixed;
	/*设置单元格之间的间距*/
	border-spacing: 0.3em;
	background-color: rgb(187, 173, 160);
}

#tblGame td {
	background-color: rgb(204, 192, 178);
	text-align: center;
	vertical-align: middle;
	font-size: 5;
	font-weight: bold;
	border: none;
}
</style>
<script type="text/javascript">
	//定义各个数字对应的背景色和字体颜色
	var arrColor = [];
	arrColor.push("rgb(238,228,218)");//2的背景色
	arrColor.push("rgb(110,100,90)");//2的字体色
	arrColor.push("rgb(236,224,202)");//4的背景色
	arrColor.push("rgb(127,115,99)");//4的字体色
	arrColor.push("rgb(243,176,123)");//8的背景色
	arrColor.push("rgb(255,234,202)");//8的字体色
	arrColor.push("rgb(246,148,99)");//16的背景色
	arrColor.push("rgb(255,235,209)");//16的字体色
	//缓存数组,每次移动之前记录下单元格的数字信息,用于undo
	var cache = [];
	window.onresize = resizeTD;
	window.onload = function() {
		resizeTD();
		resetGame();
		$("tdRestart").onclick = function() {
			resetGame();
		}
		document.body.onkeypress = function(e) {
			switch (e.charCode) {
			case 119:
				//按下w键视作按方向键上
				console.log("press w");
				move(1);
				break;
			case 115:
				//按下s键视作按方向键下
				console.log("press s");
				move(2);
				break;
			case 97:
				//按下a键视作按方向键左
				console.log("press a");
				move(3);
				break;
			case 100:
				//按下d键视作按方向键右
				console.log("press d");
				move(4);
			}
		}
		$("tdUndo").onclick = function() {
			//获取游戏表格
			var tblGame = $("tblGame");
			//获取游戏表格的所有单元格
			var td_tblGame = tblGame.getElementsByTagName("td");
			var tmpCache = cache.pop();
			if (tmpCache) {
				for ( var i = 0; i < tmpCache.length; i++) {
					var text = tmpCache[i];
					td_tblGame[i].innerText = text;
					if (text == "") {
						td_tblGame[i].style.backgroundColor = "rgb(204, 192, 178)";
					} else {
						var num = parseInt(text);
						td_tblGame[i].style.backgroundColor = getBgColor(num);
						td_tblGame[i].style.color = getColor(num);
					}
				}
			}
		}
	};
	function resizeTD() {
		//获取游戏表格
		var tblGame = $("tblGame");
		//获取游戏表格的所有单元格
		var td_tblGame = tblGame.getElementsByTagName("td");
		for ( var i = 0; i < td_tblGame.length; i++) {
			//设置单元格的高度
			td_tblGame[i].style.height = td_tblGame[i].offsetWidth + "px";
			//设置单元格的字体大小
			td_tblGame[i].style.fontSize = Math.round(td_tblGame[i].offsetWidth * 0.5) + "px";
		}
	}
	//重置游戏
	function resetGame() {
		//获取游戏表格
		var tblGame = $("tblGame");
		//获取游戏表格的所有单元格
		var td_tblGame = tblGame.getElementsByTagName("td");
		for ( var i = 0; i < td_tblGame.length; i++) {
			//清空所有单元格中的数据
			td_tblGame[i].innerText = "";
			//重置所有单元的背景色为初始状态
			td_tblGame[i].style.backgroundColor = "rgb(204, 192, 178)";
		}
		//随机选取两个不一样的单元格,设置他们的数据为2或者4
		var firstRandom = getRandom(0, 15);
		var secondRandom = firstRandom;
		while (secondRandom == firstRandom) {
			secondRandom = getRandom(0, 15);
		}
		var num = getRandom(1, 2) * 2;
		var color = getColor(num);
		var bgColor = getBgColor(num);
		td_tblGame[firstRandom].innerText = num;
		td_tblGame[firstRandom].style.color = color;
		td_tblGame[firstRandom].style.backgroundColor = bgColor;
		num = getRandom(1, 2) * 2;
		color = getColor(num);
		bgColor = getBgColor(num);
		td_tblGame[secondRandom].innerText = num;
		td_tblGame[secondRandom].style.color = color;
		td_tblGame[secondRandom].style.backgroundColor = bgColor;
		//清空当前分数
		var tdScore = $("tdScore");
		tdScore.innerText = 0;
		//设置缓存
		cache.length = 0;
		var tmpCache = [];
		for ( var i = 0; i < td_tblGame.length; i++) {
			tmpCache.push(td_tblGame[i].innerText);
		}
		cache.push(tmpCache);
	}
	function $(id) {
		return document.getElementById(id);
	}
	//获取随机数,范围begin-end
	function getRandom(begin, end) {
		var range = end - begin;
		return begin + Math.round(Math.random() * range);
	}
	//获取某个数字对应的字体颜色
	function getColor(num) {
		var result = Math.log(num) / Math.log(2);
		return arrColor[result * 2 - 1];
	}
	//获取某个数字对应的背景颜色
	function getBgColor(num) {
		var result = Math.log(num) / Math.log(2);
		return arrColor[result * 2 - 2];
	}
	//移动方法,按照direction方向区分
	//1表示上,2表示下,3表示左,4表示右
	function move(direction) {
		//a表示循环变量i前面的因子,b表示循环变量j前面的因子,c表示常量
		var a, b, c;
		switch (direction) {
		case 1:
			a = 1;
			b = 4;
			c = 0;
			break;
		case 2:
			a = 1;
			b = -4;
			c = 12;
			break;
		case 3:
			a = 4;
			b = 1;
			c = 0;
			break;
		case 4:
			a = 4;
			b = -1;
			c = 3;
			break;
		}
		//获取游戏表格
		var tblGame = $("tblGame");
		//获取游戏表格的所有单元格
		var td_tblGame = tblGame.getElementsByTagName("td");
		//记录单元格的数字信息,用于undo,暂时只能undo一步,用于调试
		//添加缓存
		var tmpCache = [];
		for ( var i = 0; i < td_tblGame.length; i++) {
			tmpCache.push(td_tblGame[i].innerText);
		}
		cache.push(tmpCache);
		//是否生成新数字的标记
		var generateNew = false;
		for ( var i = 0; i < 4; i++) {
			//去除空格,其实就是将稀疏数组转换成密集数组
			for ( var j = 0; j < 4; j++) {
				text = td_tblGame[a * i + b * j + c].innerText;
				num = text == "" ? 0 : parseInt(text);
				if (text != "") {
					//如果当前单元格的内容不为空,则向前遍历找到第一个内容不为空的单元格
					//则该单元格的索引+1即为交换位置的点
					for ( var k = j - 1; k > -1; k--) {
						var textPos = td_tblGame[a * i + b * k + c].innerText;
						if (textPos != "") {
							break;
						}
					}
					if (k + 1 != j) {
						//将生成新数字标记置为true
						generateNew = true;
						//交换两个单元格的值
						td_tblGame[a * i + b * (k + 1) + c].innerText = text;
						td_tblGame[a * i + b * (k + 1) + c].style.backgroundColor = getBgColor(num);
						td_tblGame[a * i + b * (k + 1) + c].style.color = getColor(num);
						td_tblGame[a * i + b * j + c].innerText = "";
						td_tblGame[a * i + b * j + c].style.backgroundColor = "rgb(204, 192, 178)";
					}
				}
			}
			//将相邻单元格数字相同的合成
			for ( var j = 0; j < 3; j++) {
				//当前单元格中的文本
				var text = td_tblGame[a * i + b * j + c].innerText;
				//当前单元格中的数字
				var num = text == "" ? 0 : parseInt(text);
				//后面单元格中的文本
				var textNext = td_tblGame[a * i + b * (j + 1) + c].innerText;
				//后面一个单元格中的数字
				var numNext = textNext == "" ? 0 : parseInt(textNext);
				//如果两个数字相等,那么当前单元格数字乘以2,清空后面的单元格
				if (num == numNext && num != 0) {
					//将生成新数字标记置为true
					generateNew = true;
					td_tblGame[a * i + b * j + c].innerText = num * 2;
					td_tblGame[a * i + b * j + c].style.backgroundColor = getBgColor(num * 2);
					td_tblGame[a * i + b * j + c].style.color = getColor(num * 2);
					td_tblGame[a * i + b * (j + 1) + c].innerText = "";
					td_tblGame[a * i + b * (j + 1) + c].style.backgroundColor = "rgb(204, 192, 178)";
				}
			}
			//去除空格,其实就是将稀疏数组转换成密集数组
			for ( var j = 0; j < 4; j++) {
				text = td_tblGame[a * i + b * j + c].innerText;
				num = text == "" ? 0 : parseInt(text);
				if (text != "") {
					//如果当前单元格的内容不为空,则向前遍历找到第一个内容不为空的单元格
					//则该单元格的索引+1即为交换位置的点
					for ( var k = j - 1; k > -1; k--) {
						var textPos = td_tblGame[a * i + b * k + c].innerText;
						if (textPos != "") {
							break;
						}
					}
					if (k + 1 != j) {
						//将生成新数字标记置为true
						generateNew = true;
						//交换两个单元格的值
						td_tblGame[a * i + b * (k + 1) + c].innerText = text;
						td_tblGame[a * i + b * (k + 1) + c].style.backgroundColor = getBgColor(num);
						td_tblGame[a * i + b * (k + 1) + c].style.color = getColor(num);
						td_tblGame[a * i + b * j + c].innerText = "";
						td_tblGame[a * i + b * j + c].style.backgroundColor = "rgb(204, 192, 178)";
					}
				}
			}
		}
		//将内容为空的单元格索引组成一个数组
		var arrIndex = [];
		for ( var i = 0; i < 16; i++) {
			text = td_tblGame[i].innerText;
			if (text == "") {
				arrIndex.push(i);
			}
		}
		if (arrIndex.length == 0) {
			//如果索引数组长度为0,则游戏结束
			alert("game over");
		} else if (generateNew) {
			//如果生成新数字标记置为true,则将所有空白单元格的索引构成一个数组,随机生成一个索引
			var randomIndex = getRandom(0, arrIndex.length - 1);
			var randomNum = getRandom(1, 2) * 2;
			td_tblGame[randomIndex].innerText = randomNum;
			td_tblGame[randomIndex].style.color = getColor(randomNum);
			td_tblGame[randomIndex].style.backgroundColor = getBgColor(randomNum);
		}

	}
</script>
</head>
<body>
	<table id="tblAll">
		<tr>
			<td width="30%"></td>
			<!-- 中间的内容列 -->
			<td width="40%">
				<div id="divMenu">
					<input type="button" id="btnMenu" value="菜单" />
				</div>
				<table id="tblScore">
					<tr>
						<td rowspan="2" id="gameName" width="40%">2048</td>
						<td class="score" width="30%">当前分</td>
						<td class="score" width="30%">最高分</td>
					</tr>
					<tr>
						<td class="score" id="tdScore">1333333</td>
						<td class="score" id="tdBest">1333333</td>
					</tr>
				</table>
				<table id="tblBtns">
					<tr>
						<td id="tdRestart">RESTART</td>
						<td id="tdUndo">UNDO</td>
					</tr>
				</table> <!-- 这个是最下面的游戏的主表格 -->
				<table id="tblGame">
					<tr>
						<td width="25%"></td>
						<td width="25%"></td>
						<td width="25%"></td>
						<td width="25%"></td>
					</tr>
					<tr>
						<td></td>
						<td></td>
						<td></td>
						<td></td>
					</tr>
					<tr>
						<td></td>
						<td></td>
						<td></td>
						<td></td>
					</tr>
					<tr>
						<td></td>
						<td></td>
						<td></td>
						<td></td>
					</tr>
				</table>
			</td>
			<td width="30%"></td>
		</tr>
	</table>
</body>
</html>

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐