使用js写一个2048

        为什么标题叫使用js写一个2048呢?因为我不会页面美化(在这里给div加外边距和内边距已经是我做页面美化的极限了)!!!!本来打算导入SemanticUI来美化页面的,结果发现SemanticUI的弹出层需要jquery支持。那我用原生js写不是显得很呆?那就不对页面做美化了,能看就行,消息提示也使用尊贵的alert()来完成吧。

首先我们创建一个html文件,在body标签体内写我们需要的东西

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<input type="button" id="initBtn" value="开始" onclick="initBoard()" /><!--开始和重新开始按钮-->
		<div id="boardDiv"></div><!--展示图片-->
	</body>
</html>

然后准备一些图片,用来展示

以我高超的美术功底,这些工作很快就能完成

在html文件同级目录下新建一个img文件夹,然后把这些图片丢进去

 开始准备写js代码

准备一些常量(分数这个东西因为我忘了写计分功能,就没啥用了)

        //棋盘
		var BOARD = [[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]];
		//行列数
		var ROW = 5;
		var COL = 5;
		//开始标志
		var startFlag = false;
		//数据列表
		var LIST = [2,4,8,16,32,64,128,256,512,1024,2048];
		//分数
		var sore = 0;
		//存储按下鼠标的位置
		var startX = 0;
		var startY = 0;
		//不移动阈值
		var LIMIT = 10;

 获取页面上一些等会要用的元素

var initBtn = document.getElementById('initBtn');
var boardDiv = document.getElementById('boardDiv');
var body = document.getElementById('body');

写几个函数(写循环的时候把i,j和行列的对应关系搞的有点混,幸亏是一个行数列数一样的矩阵)

初始化棋盘的函数

		/**
		 * 初始化棋盘
		 */
		function initBoard(){
			startFlag = true;
			initBtn.value = "重新开始";
			for(var i = 0; i < ROW; i++){
				for(var j = 0; j < COL; j++){
					BOARD[i][j] = 0;
				}
			}
			var count = 0;
			while(count < 4){
				var i = Math.floor(Math.random() * COL);
				var j = Math.floor(Math.random() * ROW);
				if(BOARD[i][j] !== 0){
					continue;
				}
				BOARD[i][j] = 2;
				count++;
			}
			showBoard();
		}

展示棋盘的函数

		/**
		 * 展示棋盘
		 */
		function showBoard(){
			boardDiv.innerHTML = "";
			for(var i = 0; i < ROW; i++){
				for(var j = 0; j < COL; j++){
					boardDiv.innerHTML += "<img src='img/" + BOARD[i][j] + ".png'/>";
				}
				boardDiv.innerHTML += "<br\>";
			}
		}

向棋盘添加数据的函数(如果棋盘满了就不加,没满就随机找一个空位添加)

		/**
		 * 添加数据到棋盘
		 */
		function addNum(){
			var flag = true;
			for(var i = 0; i < COL; i++){
				for(var j = 0; j < ROW; j++){
					if(0 == BOARD[i][j]){
						flag = false;
						break;
					}
				}
			}
			if(flag){
				return;
			}
			var x;
			var y;
			do{
				x = Math.floor(Math.random() * COL);
				y = Math.floor(Math.random() * ROW);
			}while(BOARD[x][y] != 0);
			BOARD[x][y] = LIST[Math.floor(Math.random() * 4)];
		}

向四个方向移动数据并合并的函数

		/**
		 * 向左合并
		 */
		function mergeLeft(){
			for(var i = 0 ; i < ROW; i++){
				//记录需要附加移动的数
				var count = (0 == BOARD[i][COL - 1]? 0 : 1);
				for(var j = COL - 1; j > 0; j--){
					if(0 == BOARD[i][j - 1] || BOARD[i][j - 1] == BOARD[i][j]){
						//相等相加
						BOARD[i][j - 1] += BOARD[i][j];
						if(2048 == BOARD[i][j - 1]){
							BOARD[i][j - 1] = 0
						}
						BOARD[i][j] = 0;
						//复制附件移动的数
						if(count > 0){
							for(k = j + 1;k < j + 1 + count;k++){
								if(k > COL - 1){
									break;
								}
								BOARD[i][k - 1] = BOARD[i][k];
								BOARD[i][k] = 0;
							}
						}
					}else if(BOARD[i][j - 1] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向右合并
		 */
		function mergeRight(){
			for(var i = 0 ; i < ROW; i++){
				var count = (0 == BOARD[i][0]? 0 : 1);
				for(var j = 0; j < COL - 1; j++){
					if(0 == BOARD[i][j + 1] || BOARD[i][j + 1] == BOARD[i][j]){
						BOARD[i][j + 1] += BOARD[i][j];
						if(2048 == BOARD[i][j + 1]){
							BOARD[i][j + 1] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = j - 1;k > j - 1 - count;k--){
								if(k < 0){
									break;
								}
								BOARD[i][k + 1] = BOARD[i][k];
								BOARD[i][k] = 0;
							}
						}
					}else if(BOARD[i][j + 1] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向下合并
		 */
		function mergeDown(){
			for(var j = 0; j < COL; j++){
				var count = (0 == BOARD[0][j]? 0 : 1);
				for(var i = 0; i < ROW - 1; i++){
					if(0 == BOARD[i + 1][j] || BOARD[i + 1][j] == BOARD[i][j]){
						BOARD[i + 1][j] += BOARD[i][j];
						if(2048 == BOARD[i + 1][j]){
							BOARD[i + 1][j] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = i - 1;k > i - 1 - count;k--){
								if(k < 0){
									break;
								}
								BOARD[k + 1][j] = BOARD[k][j];
								BOARD[k][j] = 0;
							}
						}
					}else if(BOARD[i + 1][j] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向上合并
		 */
		function mergeUp(){
			for(var j = 0; j < COL; j++){
				var count = (0 == BOARD[ROW - 1][j]? 0 : 1);
				for(var i = ROW - 1; i > 0; i--){
					if(0 == BOARD[i - 1][j] || BOARD[i - 1][j] == BOARD[i][j]){
						BOARD[i - 1][j] += BOARD[i][j];
						if(2048 == BOARD[i - 1][j]){
							BOARD[i - 1][j] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = i + 1;k < i + 1 + count;k++){
								if(k > ROW - 1){
									break;
								}
								BOARD[k - 1][j] = BOARD[k][j];
								BOARD[k][j] = 0;
							}
						}
					}else if(BOARD[i - 1][j] != BOARD[i][j]){
						count++;
					}
				}
			}
		}

判断游戏结束的函数(游戏结束的判定标准是数据无法移动也无法合并)

		/**
		 * 判断当前位置是否可以使游戏继续
		 * @param {Object} x x坐标
		 * @param {Object} y y坐标
		 */
		function coludContinue(x,y){
			if(0 == BOARD[x][y]){
				return true;
			}
			return  BOARD[x - 1][y] == BOARD[x][y] ||
					BOARD[x][y - 1] == BOARD[x][y] ||
					BOARD[x][y + 1] == BOARD[x][y] ||
					BOARD[x + 1][y] == BOARD[x][y];
		}
		
		/**
		 * 判断游戏是否失败
		 */
		function isFalse(){
			for(var x = 0; x < COL; x++){
				if(0 == BOARD[0][x] || 0 == BOARD[ROW - 1][x] || 0 == BOARD[x][0] || 0 == BOARD[x][COL - 1]){
					return false;
				}
			}
			for(var i = 1; i < ROW - 1; i++){
				for(var j = 1; j < COL - 1; j++){
					if(coludContinue(i,j)){
						return false;
					}
				}
			}
			return true;
		}

判断当前用户指定的移动方向以及游戏进行的函数

		/**
		 * 鼠标按下时获取按下时的坐标
		 * @param {Object} event 鼠标按下事件,js自动传入
		 */
		document.onmousedown = function(event){
			startX = event.pageX;
			startY = event.pageY;
		}
		
		/**
		 * 鼠标松开时判断是否要进行移动
		 * @param {Object} event 鼠标松开事件,js自动传入
		 */
		document.onmouseup = function(event){
			if(!startFlag){
				return;
			}
			if(0 == startX && 0 == startY){
				return
			}
			var endX = event.pageX;
			var endY = event.pageY;
			var x = endX - startX;
			var y = endY - startY;
			startX = 0;
			startY = 0;
			if(x > LIMIT || x < -LIMIT || y > LIMIT || y < -LIMIT){
				var absX = Math.abs(x);
				var absY = Math.abs(y);
				if(absX > absY){
					if(x > 0){
						mergeRight();
					}else{
						mergeLeft();
					}
				}else{
					if(y > 0){
						mergeDown();
					}else{
						mergeUp();
					}
				}
				if(isFalse()){
					alert("您输了");
					startFlag = false;
				}
				addNum();
				showBoard();
			}
		}

完整的代码长这个样子

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
		#boardDiv{
			margin-top: 10px;
		}
		img{
			margin-top: 2px;
			margin-right: 2px;
		}
		</style>
	</head>
	<body id="body" onselectstart="return false">
		<input type="button" id="initBtn" value="开始" onclick="initBoard()" /><!--开始和重新开始按钮-->
		<div id="boardDiv"></div><!--展示图片-->
	</body>
	<script>
		//棋盘
		var BOARD = [[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]
					,[0,0,0,0,0]];
		//行列数
		var ROW = 5;
		var COL = 5;
		//开始标志
		var startFlag = false;
		//数据列表
		var LIST = [2,4,8,16,32,64,128,256,512,1024,2048];
		//分数
		var sore = 0;
		//存储按下鼠标的位置
		var startX = 0;
		var startY = 0;
		//不移动阈值
		var LIMIT = 10;
		
		var initBtn = document.getElementById('initBtn');
		var boardDiv = document.getElementById('boardDiv');
		var body = document.getElementById('body');
		var sorceMsg = document.getElementById('sorceMsg');
		
		/**
		 * 初始化棋盘
		 */
		function initBoard(){
			startFlag = true;
			initBtn.value = "重新开始";
			for(var i = 0; i < ROW; i++){
				for(var j = 0; j < COL; j++){
					BOARD[i][j] = 0;
				}
			}
			var count = 0;
			while(count < 4){
				var i = Math.floor(Math.random() * COL);
				var j = Math.floor(Math.random() * ROW);
				if(BOARD[i][j] !== 0){
					continue;
				}
				BOARD[i][j] = 2;
				count++;
			}
			showBoard();
		}
		
		/**
		 * 添加数据到棋盘
		 */
		function addNum(){
			var flag = true;
			for(var i = 0; i < COL; i++){
				for(var j = 0; j < ROW; j++){
					if(0 == BOARD[i][j]){
						flag = false;
						break;
					}
				}
			}
			if(flag){
				return;
			}
			var x;
			var y;
			do{
				x = Math.floor(Math.random() * COL);
				y = Math.floor(Math.random() * ROW);
			}while(BOARD[x][y] != 0);
			BOARD[x][y] = LIST[Math.floor(Math.random() * 4)];
		}
		
		
		/**
		 * 展示棋盘
		 */
		function showBoard(){
			boardDiv.innerHTML = "";
			for(var i = 0; i < ROW; i++){
				for(var j = 0; j < COL; j++){
					boardDiv.innerHTML += "<img src='img/" + BOARD[i][j] + ".png'/>";
				}
				boardDiv.innerHTML += "<br\>";
			}
		}
		
		
		/**
		 * 向左合并
		 */
		function mergeLeft(){
			for(var i = 0 ; i < ROW; i++){
				//记录需要附加移动的数
				var count = (0 == BOARD[i][COL - 1]? 0 : 1);
				for(var j = COL - 1; j > 0; j--){
					if(0 == BOARD[i][j - 1] || BOARD[i][j - 1] == BOARD[i][j]){
						//相等相加
						BOARD[i][j - 1] += BOARD[i][j];
						if(2048 == BOARD[i][j - 1]){
							BOARD[i][j - 1] = 0
						}
						BOARD[i][j] = 0;
						//复制附件移动的数
						if(count > 0){
							for(k = j + 1;k < j + 1 + count;k++){
								if(k > COL - 1){
									break;
								}
								BOARD[i][k - 1] = BOARD[i][k];
								BOARD[i][k] = 0;
							}
						}
					}else if(BOARD[i][j - 1] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向右合并
		 */
		function mergeRight(){
			for(var i = 0 ; i < ROW; i++){
				var count = (0 == BOARD[i][0]? 0 : 1);
				for(var j = 0; j < COL - 1; j++){
					if(0 == BOARD[i][j + 1] || BOARD[i][j + 1] == BOARD[i][j]){
						BOARD[i][j + 1] += BOARD[i][j];
						if(2048 == BOARD[i][j + 1]){
							BOARD[i][j + 1] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = j - 1;k > j - 1 - count;k--){
								if(k < 0){
									break;
								}
								BOARD[i][k + 1] = BOARD[i][k];
								BOARD[i][k] = 0;
							}
						}
					}else if(BOARD[i][j + 1] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向下合并
		 */
		function mergeDown(){
			for(var j = 0; j < COL; j++){
				var count = (0 == BOARD[0][j]? 0 : 1);
				for(var i = 0; i < ROW - 1; i++){
					if(0 == BOARD[i + 1][j] || BOARD[i + 1][j] == BOARD[i][j]){
						BOARD[i + 1][j] += BOARD[i][j];
						if(2048 == BOARD[i + 1][j]){
							BOARD[i + 1][j] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = i - 1;k > i - 1 - count;k--){
								if(k < 0){
									break;
								}
								BOARD[k + 1][j] = BOARD[k][j];
								BOARD[k][j] = 0;
							}
						}
					}else if(BOARD[i + 1][j] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 向上合并
		 */
		function mergeUp(){
			for(var j = 0; j < COL; j++){
				var count = (0 == BOARD[ROW - 1][j]? 0 : 1);
				for(var i = ROW - 1; i > 0; i--){
					if(0 == BOARD[i - 1][j] || BOARD[i - 1][j] == BOARD[i][j]){
						BOARD[i - 1][j] += BOARD[i][j];
						if(2048 == BOARD[i - 1][j]){
							BOARD[i - 1][j] = 0
						}
						BOARD[i][j] = 0;
						if(count > 0){
							for(k = i + 1;k < i + 1 + count;k++){
								if(k > ROW - 1){
									break;
								}
								BOARD[k - 1][j] = BOARD[k][j];
								BOARD[k][j] = 0;
							}
						}
					}else if(BOARD[i - 1][j] != BOARD[i][j]){
						count++;
					}
				}
			}
		}
		
		/**
		 * 判断当前位置是否可以使游戏继续
		 * @param {Object} x x坐标
		 * @param {Object} y y坐标
		 */
		function coludContinue(x,y){
			if(0 == BOARD[x][y]){
				return true;
			}
			return  BOARD[x - 1][y] == BOARD[x][y] ||
					BOARD[x][y - 1] == BOARD[x][y] ||
					BOARD[x][y + 1] == BOARD[x][y] ||
					BOARD[x + 1][y] == BOARD[x][y];
		}
		
		/**
		 * 判断游戏是否失败
		 */
		function isFalse(){
			for(var x = 0; x < COL; x++){
				if(0 == BOARD[0][x] || 0 == BOARD[ROW - 1][x] || 0 == BOARD[x][0] || 0 == BOARD[x][COL - 1]){
					return false;
				}
			}
			for(var i = 1; i < ROW - 1; i++){
				for(var j = 1; j < COL - 1; j++){
					if(coludContinue(i,j)){
						return false;
					}
				}
			}
			return true;
		}
		
		/**
		 * 鼠标按下时获取按下时的坐标
		 * @param {Object} event 鼠标按下事件,js自动传入
		 */
		document.onmousedown = function(event){
			startX = event.pageX;
			startY = event.pageY;
		}
		
		/**
		 * 鼠标松开时判断是否要进行移动
		 * @param {Object} event 鼠标松开事件,js自动传入
		 */
		document.onmouseup = function(event){
			if(!startFlag){
				return;
			}
			if(0 == startX && 0 == startY){
				return
			}
			var endX = event.pageX;
			var endY = event.pageY;
			var x = endX - startX;
			var y = endY - startY;
			startX = 0;
			startY = 0;
			if(x > LIMIT || x < -LIMIT || y > LIMIT || y < -LIMIT){
				var absX = Math.abs(x);
				var absY = Math.abs(y);
				if(absX > absY){
					if(x > 0){
						mergeRight();
					}else{
						mergeLeft();
					}
				}else{
					if(y > 0){
						mergeDown();
					}else{
						mergeUp();
					}
				}
				if(isFalse()){
					alert("您输了");
					startFlag = false;
				}
				addNum();
				showBoard();
			}
		}
		
	</script>
</html>

跑一下试试

跑起来了也没有报错,欸嘿

 开始瞧瞧

 失败提示

 我需要的功能都完成了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值