欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

html + css + js使用HBuilder开发工具做2048益智游戏

程序员文章站 2022-03-30 21:19:17
html + css + js使用HBuilder开发工具做2048益智游戏今天使用html + css + js给同学们做了一个简易版的2048益智游戏,希望大家按照步骤勤加练习,在编码的坑里早日踏上康庄大道,祝前程似锦!效果图:开发思路:一、使用HBuilder工具创建空白html项目创建项目时路径尽量不要有中文路径二、创建js和css文件备用项目目录:三、书写html标签引入css和js文件:书写html标签:html标签的代码,直接放在标签中即可:&l...

2048–>html + css + js使用HBuilder开发工具做2048益智游戏

今天使用html + css + js给同学们做了一个简易版的2048益智游戏,希望大家按照步骤勤加练习,在编码的坑里早日踏上康庄大道,祝前程似锦!

效果图:
html + css + js使用HBuilder开发工具做2048益智游戏
附源码github链接:
https://github.com/LittleGreyKing-FriedBlackYoFeed-xoox/2048.git

开发思路:

一、使用HBuilder工具创建空白html项目
html + css + js使用HBuilder开发工具做2048益智游戏
创建项目时路径尽量不要有中文路径
html + css + js使用HBuilder开发工具做2048益智游戏

二、创建js和css文件备用
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
项目目录:
html + css + js使用HBuilder开发工具做2048益智游戏

三、书写html标签
引入css和js文件:
html + css + js使用HBuilder开发工具做2048益智游戏
书写html标签:
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
html标签的代码,直接放在body标签中即可:

index.html

<header>
			<h1>2048</h1>
		</header>
		<div id="gamePanel">
			<p><a class="button" id="newGame">New Game</a> Score: <span id="score">0</span><span class="writer">小灰灰版</span></p>
			<div id="gridPanel">
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="cell " id="cell00"> </div>
				<div class="cell " id="cell01"> </div>
				<div class="cell " id="cell02"> </div>
				<div class="cell " id="cell03"> </div>

				<div class="cell " id="cell10"> </div>
				<div class="cell " id="cell11"> </div>
				<div class="cell " id="cell12"> </div>
				<div class="cell " id="cell13"> </div>

				<div class="cell " id="cell20"> </div>
				<div class="cell " id="cell21"> </div>
				<div class="cell " id="cell22"> </div>
				<div class="cell " id="cell23"> </div>

				<div class="cell " id="cell30"> </div>
				<div class="cell " id="cell31"> </div>
				<div class="cell " id="cell32"> </div>
				<div class="cell " id="cell33"> </div>

			</div>
			<div id="gameOver">
				<div>
					<!--背景 -->
				</div>
				<p>
					<!-- 前景 -->
					Game Over!<br>
					Score: <span id="finalScore">0</span><br>
					<a class="button" id="restart">Try Again!</a>
				</p>
			</div>
		</div>

四、绘制css样式表
html + css + js使用HBuilder开发工具做2048益智游戏
2048.css


* {
	padding: 0;
	margin: 0;

}

div,
p,
h1,
h2,
a,
span {
	font-family: Arial;
	font-weight: bold;
}

header {
	padding-top: 16px;
}

h1 {
	font-size: 40px;
	font-weight: bold;
	text-align: center;
}

#gamePanel {
	margin: 0 auto;
	width: 500px;
	position: relative;
}

#gridPanel {
	width: 480px;
	height: 480px;
	background: #BBADA0;
	border-radius: 10px;
	padding: 20px 0 0 20px;
	position: relative;
}

#gamePanel p {
	padding: 8px;
}

/* 按钮样式 */
.button {
	display: inline-block;
	padding: 10px;
	background: #9F8B77;
	border-radius: 6px;
	color: #FFF;
	cursor: pointer;
}

.grid,
.cell {
	width: 100px;
	height: 100px;
	border-radius: 6px;
}

/* 背景网格 */
#gamePanel .grid {
	background-color: #ccc0b3;
	float: left;
	margin: 0 20px 20px 0;
}

/* 格式化前景单元格中位置 */
.cell {
	position: absolute;
	line-height: 100px;
	vertical-align: middle;
	text-align: center;
	font-size: 60px;
	color: #776E65;
}

/* 前景格中的行位置 */
#cell00,
#cell01,
#cell02,
#cell03 {
	top: 20;
}

#cell10,
#cell11,
#cell12,
#cell13 {
	top: 140px;
}

#cell20,
#cell21,
#cell22,
#cell23 {
	top: 260px;
}

#cell30,
#cell31,
#cell32,
#cell33 {
	top: 380px;
}

/* 前景格中的列位置 */
#cell00,
#cell10,
#cell20,
#cell30 {
	left: 20px;
}

#cell01,
#cell11,
#cell21,
#cell31 {
	left: 140px;
}

#cell02,
#cell12,
#cell22,
#cell32 {
	left: 260px;
}

#cell03,
#cell13,
#cell23,
#cell33 {
	left: 380px;
}

/* 数字显示效果 */
.num8,
.num16,
.num32,
.num64,
.num128,
.num256,
.num512,
.num1024,
.num2048,
.num4096,
.num8192 {
	color: #fff;
}

.num1024,
.num2048,
.num4096,
.num8192 {
	font-size: 40px;
}

.num2 {
	background: #eee4da;
}

.num4 {
	background: #ede0c8;
}

.num8 {
	background: #f2b179;
}

.num16 {
	background: #f59563;
}

.num32 {
	background: #f67c5f;
}

.num64 {
	background: #f65e3b;
}

.num128 {
	background: #edcf72;
}

.num256 {
	background: #edcc61;
}

.num512 {
	background: #9c0;
}

.num1024 {
	background: #33b5e5;
}

.num2048 {
	background: #09c;
}

.num4096 {
	background: #a6c;
}

.num8192 {
	background: #93c;
}

/* 格式化Game Over的样式 */
#gameOver {
	display: none;
	position: absolute;
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
}

#gameOver div {
	width: 100%;
	height: 100%;
	background: #555;
	filter: alpha(Opacity=50);
	-moz-opacity: 0.5;
	opacity: 0.5;
}

#gameOver p {
	position: absolute;
	top: 150px;
	left: 100px;
	border-radius: 10px;
	width: 300px;
	border: 1px solid #EDCF72;
	background: #fff;
	line-height: 1.6em;
	font-size: 30px;
	color: #000;
	text-align: center;
}

.writer {
	width: 80px;
	margin-left: 30%;
}

五、创造JS事件函数

html + css + js使用HBuilder开发工具做2048益智游戏
animation.js

    	//动画效果工具对象
    	var animation = {
    		tasks:[], //动画任务数据
    		timer:null,//动画定时器
			times:10, //定时器次数
			interval:1000/60,//定时器间隔
			add:function(obj, top, left){
				
				//动画已经开始了,不能添加任务了!
				if(this.timer){
					return false;
				}
				if(! obj){
					return false;
				}
				
				//计算移动步伐
				var t = (top - obj.offsetTop)/this.times;
				var l = (left - obj.offsetLeft)/this.times;
				
				//添加动画任务,其中obj是被移动到对象,top, left是移动以后的位置
				var task = {
					topStep:t,
					leftStep:l,
					element:obj,	
					step:function(){
						var t = this.element.offsetTop;
						this.element.style.top = (t+ this.topStep )+"px";
						var l = this.element.offsetLeft;
						this.element.style.left = (l+ this.leftStep )+"px";		
					},
					clear:function(){
						this.element.style.top = "";
						this.element.style.left = "";
					}
				};
				this.tasks[this.tasks.length]=task; 
				return true;
			},
    		start:function(callback){
    			//如果定时器已经启动,就不能再启动定时器了
    			if(this.timer){
    				return false;
    			}

				console.log("STATRING");
				if(this.tasks.length==0){
					if(callback){
						callback();
					}
					return false;	
				}
				
				//如果有callback就交给this.callback
				if(callback){
					this.callback = callback;
				}
				this.timer = setInterval(function(){
					//console.log("timeOut");
					//console.log(animation.times);
					
					for(var i=0; i<animation.tasks.length; i++){
						var task = animation.tasks[i];
						task.step();
					}
					
					animation.times--;
					if(animation.times < 0){
						animation.stop();
					}
				}, this.interval);
				return true;
    		},
    		stop: function(){
    			if(this.timer){
    				window.clearInterval(this.timer);
    				this.timer=null;
    				this.times=10;
    				
    			}
    			
    			//结束以后执行callback()
    			if(this.callback){
    				this.callback();
    			}
				for(var i=0; i<this.tasks.length; i++){
					var task = this.tasks[i];
					task.clear();
				}    			
				this.tasks = [];//清空动画任务
    		},
    		callback:null //动画结束时候执行的方法
    	};

JS的部分还有index.html中包含的:
html + css + js使用HBuilder开发工具做2048益智游戏
index.html 中包含的js部分

<script type="text/javascript">
			//game 封装了2048的数据和核心算法
			var cells = [
				[2, 0, 0, 0],
				[0, 32, 0, 0],
				[0, 4, 0, 0],
				[0, 0, 2048, 0]
			];
			//游戏进行中
			var PLAYING = 0;
			//方块正在移动动画处理中,期间不能响应键盘事件
			var CELL_MOVEING = 1;
			//游戏结束了,结束了就不能响应键盘事件了
			var GAME_OVER = 2;

			var score = 0;

			//当前游戏状态
			var state = PLAYING;

			//动态效果开关,打开后可以绘制方块的移动动画效果
			var effect = true;

			/* 向上的动作, */
			function upAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveUp()) {
					return false;
				}
				//每次处理一个列
				for (var col = 0; col < 4; col++) {
					//每一个列中 从放方向判断是否需要移动处理
					upCol(col);
				}
				return true;
			}
			// 处理一个列的移动 
			function upCol(col) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var row = 0; row < 4;) {
					var current = cells[row][col];
					var nextRow = getNextInCol(col, row + 1, 1);
					//没有下一个,就直接结束了
					if (nextRow == -1) {
						return;
					}
					var next = cells[nextRow][col];

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[nextRow][col] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[nextRow][col] = 0;

						score += cells[row][col];

						row++;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						row++;
					}
				}
			}

			function getNextInCol(col, startRow, step) {
				var row = startRow;
				while (true) {
					if (row < 0 || row >= 4) {
						return -1;
					}
					if (cells[row][col] != 0) {
						return row;
					}
					row += step;
				}
			}

			function getNextInRow(row, startCol, step) {
				var col = startCol;
				while (true) {
					if (col < 0 || col >= 4) {
						return -1;
					}
					if (cells[row][col] != 0) {
						return col;
					}
					col += step;
				}
			}

			function downAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveDown()) {
					return false;
				}
				//每次处理一个列
				for (var col = 0; col < 4; col++) {
					//每一个列中 从放方向判断是否需要移动处理
					downCol(col);
				}
				return true;
			}
			// 处理一个列的移动
			function downCol(col) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var row = 3; row >= 0;) {
					var current = cells[row][col];
					var nextRow = getNextInCol(col, row - 1, -1);
					//没有下一个,就直接结束了
					if (nextRow == -1) {
						return;
					}
					var next = cells[nextRow][col];

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[nextRow][col] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[nextRow][col] = 0;

						score += cells[row][col];

						row--;

						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						row--;
					}
				}
			}

			function leftAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveLeft()) {
					return false;
				}
				//每次处理一个行
				for (var row = 0; row < 4; row++) {
					//每一个行中 从放方向判断是否需要移动处理
					moveLeft(row);
				}
				return true;
			}
			// 处理一个列的移动
			function moveLeft(row) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var col = 0; col < 4;) {
					var current = cells[row][col];
					var nextCol = getNextInRow(row, col + 1, 1);
					//没有下一个,就直接结束了
					if (nextCol == -1) {
						return;
					}
					var next = cells[row][nextCol];

					//console.log("next:"+next);
					//console.log("current:"+current);

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[row][nextCol] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[row][nextCol] = 0;

						score += cells[row][col];

						col++;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						col++;
					}
				}
			}

			function rightAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveRight()) {
					return false;
				}
				//每次处理一个行
				for (var row = 0; row < 4; row++) {
					//每一个行中 从放方向判断是否需要移动处理
					moveRight(row);
				}
				return true;
			}
			// 处理一个列的移动
			function moveRight(row) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var col = 3; col >= 0;) {
					var current = cells[row][col];
					var nextCol = getNextInRow(row, col - 1, -1);
					//没有下一个,就直接结束了
					if (nextCol == -1) {
						return;
					}
					var next = cells[row][nextCol];

					//console.log("next:"+next);
					//console.log("current:"+current);

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[row][nextCol] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[row][nextCol] = 0;


						score += cells[row][col];

						col--;

						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						col--;
					}
				}
			}

			function canMoveUp() {
				for (var col = 0; col < 4; col++) {
					for (var row = 1; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row - 1][col] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row - 1][col])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveDown() {
				for (var col = 0; col < 4; col++) {
					for (var row = 0; row < 3; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row + 1][col] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row + 1][col])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveLeft() {
				for (var col = 1; col < 4; col++) {
					for (var row = 0; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row][col - 1] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row][col - 1])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveRight() {
				for (var col = 0; col < 3; col++) {
					for (var row = 0; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row][col + 1] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row][col + 1])) {
							return true;
						}
					}
				}
				return false;
			}


			function test() {
				rightAction();
				state = CELL_MOVEING;
				animation.start(function() {
					//console.log("update");
					randomNumber();
					updateView();
					state = PLAYING;
				});
			}

			//更新显示,将表格中的数据,更新到界面显示
			function updateView() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						var n = cells[row][col];
						var cell = $("cell" + row + col);
						//清楚显示的数据和显示样式
						cell.className = "cell";
						cell.innerHTML = "";
						if (n > 0) {
							//更新显示样式
							cell.className = "cell num" + n;
							//更新显示的数字
							cell.innerHTML = n;
						}
					}
				}

				$("score").innerHTML = score;
				$("finalScore").innerHTML = score;

			}
			//检查当前的表格中是否是满的,如果满了返回true,否则返回false
			function full() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 0) {
							return false;
						}
					}
				}
				return true;
			}
			//向表格随机插入一个数字,如果插入成功返回true,插入失败返回false
			function randomNumber() {
				if (full()) {
					return false;
				}
				while (true) {
					var col = parseInt(Math.random() * 4);
					var row = parseInt(Math.random() * 4);
					if (cells[row][col] == 0) {
						var n = Math.random() < 0.5 ? 2 : 4;
						cells[row][col] = n;
						return true;
					}
				}
			}

			function startAction() {
				$("gameOver").style.display = "none";
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						cells[row][col] = 0;
					}
				}
				score = 0;
				randomNumber();
				randomNumber();
				updateView();
				state = PLAYING;
			}
			//元素查询方法
			function $(id) {
				return document.getElementById(id);
			}

			function has8192() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 8192) {
							return true;
						}
					}
				}
			}

			function hasSpace() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 0) {
							return true;
						}
					}
				}
			}


			/* 显示游戏结束界面 */
			function gameOver() {
				//发现8192游戏结束
				if (has8192()) {
					state = GAME_OVER;
					$("gameOver").style.display = "block";
					return true;
				}

				//发现空位置,游戏不结束    	
				if (hasSpace()) {
					return false;
				}

				//能够移动游戏不结束
				if (canMoveUp() || canMoveDown() || canMoveLeft() || canMoveRight()) {
					return false;
				}
				state = GAME_OVER;
				$("gameOver").style.display = "block";
				return true;
			}

			//软件启动初始代码
			window.onload = function() {
				$("newGame").onclick = function() {
					if (state == PLAYING)
						startAction();
				}
				$("restart").onclick = function() {
					if (state == GAME_OVER)
						startAction();
				}
				startAction();
				//监听键盘事件
				document.onkeydown = function(event) {
					if (state != PLAYING) {
						return;
					}
					var move = false;
					switch (event.keyCode) {
						case 37: //left
							move = leftAction();
							break;
						case 38: //up
							move = upAction();
							break;
						case 39: //right
							move = rightAction();
							break;
						case 40: //down
							move = downAction();
							break;
					}
					if (!move) {
						return;
					}
					if (effect) {
						state = CELL_MOVEING;
						animation.start(function() {
							//console.log("update");
							updateView();
							state = PLAYING;
							if (!gameOver()) {
								setTimeout(function() {
									randomNumber();
									updateView();
								}, 100);
							}
						});
					} else {
						if (!gameOver()) {
							setTimeout(function() {
								randomNumber();
								updateView();
							}, 100);
						}

						updateView();
						state = PLAYING;
					}
					gameOver();
				}; // 5211 0842 8479 快捷快递
			}
		</script>

六、测试和运行

配置和运行时记得要打开index.html再执行。
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
html + css + js使用HBuilder开发工具做2048益智游戏
完毕。

七、懒人版全部源码

很多同学喜欢html 和 css 和 js都放在同一个文件中,我给大家也做了一个懒人版的2048,以下提供源码:

2048.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>2048-懒人版</title>
		<!-- 2048.css -->
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			
			}
			
			div,
			p,
			h1,
			h2,
			a,
			span {
				font-family: Arial;
				font-weight: bold;
			}
			
			header {
				padding-top: 16px;
			}
			
			h1 {
				font-size: 40px;
				font-weight: bold;
				text-align: center;
			}
			
			#gamePanel {
				margin: 0 auto;
				width: 500px;
				position: relative;
			}
			
			#gridPanel {
				width: 480px;
				height: 480px;
				background: #BBADA0;
				border-radius: 10px;
				padding: 20px 0 0 20px;
				position: relative;
			}
			
			#gamePanel p {
				padding: 8px;
			}
			
			/* 按钮样式 */
			.button {
				display: inline-block;
				padding: 10px;
				background: #9F8B77;
				border-radius: 6px;
				color: #FFF;
				cursor: pointer;
			}
			
			.grid,
			.cell {
				width: 100px;
				height: 100px;
				border-radius: 6px;
			}
			
			/* 背景网格 */
			#gamePanel .grid {
				background-color: #ccc0b3;
				float: left;
				margin: 0 20px 20px 0;
			}
			
			/* 格式化前景单元格中位置 */
			.cell {
				position: absolute;
				line-height: 100px;
				vertical-align: middle;
				text-align: center;
				font-size: 60px;
				color: #776E65;
			}
			
			/* 前景格中的行位置 */
			#cell00,
			#cell01,
			#cell02,
			#cell03 {
				top: 20;
			}
			
			#cell10,
			#cell11,
			#cell12,
			#cell13 {
				top: 140px;
			}
			
			#cell20,
			#cell21,
			#cell22,
			#cell23 {
				top: 260px;
			}
			
			#cell30,
			#cell31,
			#cell32,
			#cell33 {
				top: 380px;
			}
			
			/* 前景格中的列位置 */
			#cell00,
			#cell10,
			#cell20,
			#cell30 {
				left: 20px;
			}
			
			#cell01,
			#cell11,
			#cell21,
			#cell31 {
				left: 140px;
			}
			
			#cell02,
			#cell12,
			#cell22,
			#cell32 {
				left: 260px;
			}
			
			#cell03,
			#cell13,
			#cell23,
			#cell33 {
				left: 380px;
			}
			
			/* 数字显示效果 */
			.num8,
			.num16,
			.num32,
			.num64,
			.num128,
			.num256,
			.num512,
			.num1024,
			.num2048,
			.num4096,
			.num8192 {
				color: #fff;
			}
			
			.num1024,
			.num2048,
			.num4096,
			.num8192 {
				font-size: 40px;
			}
			
			.num2 {
				background: #eee4da;
			}
			
			.num4 {
				background: #ede0c8;
			}
			
			.num8 {
				background: #f2b179;
			}
			
			.num16 {
				background: #f59563;
			}
			
			.num32 {
				background: #f67c5f;
			}
			
			.num64 {
				background: #f65e3b;
			}
			
			.num128 {
				background: #edcf72;
			}
			
			.num256 {
				background: #edcc61;
			}
			
			.num512 {
				background: #9c0;
			}
			
			.num1024 {
				background: #33b5e5;
			}
			
			.num2048 {
				background: #09c;
			}
			
			.num4096 {
				background: #a6c;
			}
			
			.num8192 {
				background: #93c;
			}
			
			/* 格式化Game Over的样式 */
			#gameOver {
				display: none;
				position: absolute;
				width: 100%;
				height: 100%;
				top: 0;
				left: 0;
			}
			
			#gameOver div {
				width: 100%;
				height: 100%;
				background: #555;
				filter: alpha(Opacity=50);
				-moz-opacity: 0.5;
				opacity: 0.5;
			}
			
			#gameOver p {
				position: absolute;
				top: 150px;
				left: 100px;
				border-radius: 10px;
				width: 300px;
				border: 1px solid #EDCF72;
				background: #fff;
				line-height: 1.6em;
				font-size: 30px;
				color: #000;
				text-align: center;
			}
			
			.writer {
				width: 80px;
				margin-left: 30%;
			}
			
		</style>
		<script type="text/javascript">
			//game 封装了2048的数据和核心算法
			var cells = [
				[2, 0, 0, 0],
				[0, 32, 0, 0],
				[0, 4, 0, 0],
				[0, 0, 2048, 0]
			];
			//游戏进行中
			var PLAYING = 0;
			//方块正在移动动画处理中,期间不能响应键盘事件
			var CELL_MOVEING = 1;
			//游戏结束了,结束了就不能响应键盘事件了
			var GAME_OVER = 2;

			var score = 0;

			//当前游戏状态
			var state = PLAYING;

			//动态效果开关,打开后可以绘制方块的移动动画效果
			var effect = true;

			/* 向上的动作, */
			function upAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveUp()) {
					return false;
				}
				//每次处理一个列
				for (var col = 0; col < 4; col++) {
					//每一个列中 从放方向判断是否需要移动处理
					upCol(col);
				}
				return true;
			}
			// 处理一个列的移动 
			function upCol(col) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var row = 0; row < 4;) {
					var current = cells[row][col];
					var nextRow = getNextInCol(col, row + 1, 1);
					//没有下一个,就直接结束了
					if (nextRow == -1) {
						return;
					}
					var next = cells[nextRow][col];

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[nextRow][col] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[nextRow][col] = 0;

						score += cells[row][col];

						row++;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						row++;
					}
				}
			}

			function getNextInCol(col, startRow, step) {
				var row = startRow;
				while (true) {
					if (row < 0 || row >= 4) {
						return -1;
					}
					if (cells[row][col] != 0) {
						return row;
					}
					row += step;
				}
			}

			function getNextInRow(row, startCol, step) {
				var col = startCol;
				while (true) {
					if (col < 0 || col >= 4) {
						return -1;
					}
					if (cells[row][col] != 0) {
						return col;
					}
					col += step;
				}
			}

			function downAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveDown()) {
					return false;
				}
				//每次处理一个列
				for (var col = 0; col < 4; col++) {
					//每一个列中 从放方向判断是否需要移动处理
					downCol(col);
				}
				return true;
			}
			// 处理一个列的移动
			function downCol(col) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var row = 3; row >= 0;) {
					var current = cells[row][col];
					var nextRow = getNextInCol(col, row - 1, -1);
					//没有下一个,就直接结束了
					if (nextRow == -1) {
						return;
					}
					var next = cells[nextRow][col];

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[nextRow][col] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[nextRow][col] = 0;

						score += cells[row][col];

						row--;

						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + nextRow + col);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						row--;
					}
				}
			}

			function leftAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveLeft()) {
					return false;
				}
				//每次处理一个行
				for (var row = 0; row < 4; row++) {
					//每一个行中 从放方向判断是否需要移动处理
					moveLeft(row);
				}
				return true;
			}
			// 处理一个列的移动
			function moveLeft(row) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var col = 0; col < 4;) {
					var current = cells[row][col];
					var nextCol = getNextInRow(row, col + 1, 1);
					//没有下一个,就直接结束了
					if (nextCol == -1) {
						return;
					}
					var next = cells[row][nextCol];

					//console.log("next:"+next);
					//console.log("current:"+current);

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[row][nextCol] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[row][nextCol] = 0;

						score += cells[row][col];

						col++;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						col++;
					}
				}
			}

			function rightAction() {
				if (state == CELL_MOVEING) {
					return false;
				}
				if (!canMoveRight()) {
					return false;
				}
				//每次处理一个行
				for (var row = 0; row < 4; row++) {
					//每一个行中 从放方向判断是否需要移动处理
					moveRight(row);
				}
				return true;
			}
			// 处理一个列的移动
			function moveRight(row) {
				//一个列中,按照方方向检查是否需要合并处理。
				for (var col = 3; col >= 0;) {
					var current = cells[row][col];
					var nextCol = getNextInRow(row, col - 1, -1);
					//没有下一个,就直接结束了
					if (nextCol == -1) {
						return;
					}
					var next = cells[row][nextCol];

					//console.log("next:"+next);
					//console.log("current:"+current);

					if (current == 0) {
						//下一个格子移动到当前位置。
						cells[row][col] = next;
						cells[row][nextCol] = 0;
						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else if (current == next) {
						//两个格子一样,就合并格子
						cells[row][col] = next + current;
						cells[row][nextCol] = 0;


						score += cells[row][col];

						col--;

						if (effect) { //如果动效开关打开,就处理动画
							// $("cell"+nextRow+col) 找到下一个对象对应的格子
							var obj = $("cell" + row + nextCol);
							var top = row * 120 + 20;
							var left = col * 120 + 20;
							animation.add(obj, top, left);
						}
					} else {
						//下个不一样,就忽略之
						col--;
					}
				}
			}

			function canMoveUp() {
				for (var col = 0; col < 4; col++) {
					for (var row = 1; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row - 1][col] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row - 1][col])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveDown() {
				for (var col = 0; col < 4; col++) {
					for (var row = 0; row < 3; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row + 1][col] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row + 1][col])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveLeft() {
				for (var col = 1; col < 4; col++) {
					for (var row = 0; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row][col - 1] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row][col - 1])) {
							return true;
						}
					}
				}
				return false;
			}

			function canMoveRight() {
				for (var col = 0; col < 3; col++) {
					for (var row = 0; row < 4; row++) {
						//格子上方是空位置, 可以移动
						if (cells[row][col] != 0 && cells[row][col + 1] == 0) {
							return true;
						}
						//格子上方相邻的相等,可以移动
						if (cells[row][col] != 0 && (cells[row][col] == cells[row][col + 1])) {
							return true;
						}
					}
				}
				return false;
			}


			function test() {
				rightAction();
				state = CELL_MOVEING;
				animation.start(function() {
					//console.log("update");
					randomNumber();
					updateView();
					state = PLAYING;
				});
			}

			//更新显示,将表格中的数据,更新到界面显示
			function updateView() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						var n = cells[row][col];
						var cell = $("cell" + row + col);
						//清楚显示的数据和显示样式
						cell.className = "cell";
						cell.innerHTML = "";
						if (n > 0) {
							//更新显示样式
							cell.className = "cell num" + n;
							//更新显示的数字
							cell.innerHTML = n;
						}
					}
				}

				$("score").innerHTML = score;
				$("finalScore").innerHTML = score;

			}
			//检查当前的表格中是否是满的,如果满了返回true,否则返回false
			function full() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 0) {
							return false;
						}
					}
				}
				return true;
			}
			//向表格随机插入一个数字,如果插入成功返回true,插入失败返回false
			function randomNumber() {
				if (full()) {
					return false;
				}
				while (true) {
					var col = parseInt(Math.random() * 4);
					var row = parseInt(Math.random() * 4);
					if (cells[row][col] == 0) {
						var n = Math.random() < 0.5 ? 2 : 4;
						cells[row][col] = n;
						return true;
					}
				}
			}

			function startAction() {
				$("gameOver").style.display = "none";
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						cells[row][col] = 0;
					}
				}
				score = 0;
				randomNumber();
				randomNumber();
				updateView();
				state = PLAYING;
			}
			//元素查询方法
			function $(id) {
				return document.getElementById(id);
			}

			function has8192() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 8192) {
							return true;
						}
					}
				}
			}

			function hasSpace() {
				for (var row = 0; row < 4; row++) {
					for (var col = 0; col < 4; col++) {
						if (cells[row][col] == 0) {
							return true;
						}
					}
				}
			}


			/* 显示游戏结束界面 */
			function gameOver() {
				//发现8192游戏结束
				if (has8192()) {
					state = GAME_OVER;
					$("gameOver").style.display = "block";
					return true;
				}

				//发现空位置,游戏不结束    	
				if (hasSpace()) {
					return false;
				}

				//能够移动游戏不结束
				if (canMoveUp() || canMoveDown() || canMoveLeft() || canMoveRight()) {
					return false;
				}
				state = GAME_OVER;
				$("gameOver").style.display = "block";
				return true;
			}

			//软件启动初始代码
			window.onload = function() {
				$("newGame").onclick = function() {
					if (state == PLAYING)
						startAction();
				}
				$("restart").onclick = function() {
					if (state == GAME_OVER)
						startAction();
				}
				startAction();
				//监听键盘事件
				document.onkeydown = function(event) {
					if (state != PLAYING) {
						return;
					}
					var move = false;
					switch (event.keyCode) {
						case 37: //left
							move = leftAction();
							break;
						case 38: //up
							move = upAction();
							break;
						case 39: //right
							move = rightAction();
							break;
						case 40: //down
							move = downAction();
							break;
					}
					if (!move) {
						return;
					}
					if (effect) {
						state = CELL_MOVEING;
						animation.start(function() {
							//console.log("update");
							updateView();
							state = PLAYING;
							if (!gameOver()) {
								setTimeout(function() {
									randomNumber();
									updateView();
								}, 100);
							}
						});
					} else {
						if (!gameOver()) {
							setTimeout(function() {
								randomNumber();
								updateView();
							}, 100);
						}

						updateView();
						state = PLAYING;
					}
					gameOver();
				}; // 5211 0842 8479 快捷快递
			}
			
			// animation.js的部分
			var animation = {
				tasks: [], //动画任务数据
				timer: null, //动画定时器
				times: 10, //定时器次数
				interval: 1000 / 60, //定时器间隔
				add: function(obj, top, left) {
			
					//动画已经开始了,不能添加任务了!
					if (this.timer) {
						return false;
					}
					if (!obj) {
						return false;
					}
			
					//计算移动步伐
					var t = (top - obj.offsetTop) / this.times;
					var l = (left - obj.offsetLeft) / this.times;
			
					//添加动画任务,其中obj是被移动到对象,top, left是移动以后的位置
					var task = {
						topStep: t,
						leftStep: l,
						element: obj,
						step: function() {
							var t = this.element.offsetTop;
							this.element.style.top = (t + this.topStep) + "px";
							var l = this.element.offsetLeft;
							this.element.style.left = (l + this.leftStep) + "px";
						},
						clear: function() {
							this.element.style.top = "";
							this.element.style.left = "";
						}
					};
					this.tasks[this.tasks.length] = task;
					return true;
				},
				start: function(callback) {
					//如果定时器已经启动,就不能再启动定时器了
					if (this.timer) {
						return false;
					}
			
					console.log("STATRING");
					if (this.tasks.length == 0) {
						if (callback) {
							callback();
						}
						return false;
					}
			
					//如果有callback就交给this.callback
					if (callback) {
						this.callback = callback;
					}
					this.timer = setInterval(function() {
						//console.log("timeOut");
						//console.log(animation.times);
			
						for (var i = 0; i < animation.tasks.length; i++) {
							var task = animation.tasks[i];
							task.step();
						}
			
						animation.times--;
						if (animation.times < 0) {
							animation.stop();
						}
					}, this.interval);
					return true;
				},
				stop: function() {
					if (this.timer) {
						window.clearInterval(this.timer);
						this.timer = null;
						this.times = 10;
			
					}
			
					//结束以后执行callback()
					if (this.callback) {
						this.callback();
					}
					for (var i = 0; i < this.tasks.length; i++) {
						var task = this.tasks[i];
						task.clear();
					}
					this.tasks = []; //清空动画任务
				},
				callback: null //动画结束时候执行的方法
			};
			
		</script>
	</head>
	<body>
		<header>
			<h1>2048</h1>
		</header>
		<div id="gamePanel">
			<p><a class="button" id="newGame">New Game</a> Score: <span id="score">0</span><span class="writer">小灰灰版</span></p>
			<div id="gridPanel">
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>
				<div class="grid"> </div>

				<div class="cell " id="cell00"> </div>
				<div class="cell " id="cell01"> </div>
				<div class="cell " id="cell02"> </div>
				<div class="cell " id="cell03"> </div>

				<div class="cell " id="cell10"> </div>
				<div class="cell " id="cell11"> </div>
				<div class="cell " id="cell12"> </div>
				<div class="cell " id="cell13"> </div>

				<div class="cell " id="cell20"> </div>
				<div class="cell " id="cell21"> </div>
				<div class="cell " id="cell22"> </div>
				<div class="cell " id="cell23"> </div>

				<div class="cell " id="cell30"> </div>
				<div class="cell " id="cell31"> </div>
				<div class="cell " id="cell32"> </div>
				<div class="cell " id="cell33"> </div>

			</div>
			<div id="gameOver">
				<div>
					<!--背景 -->
				</div>
				<p>
					<!-- 前景 -->
					Game Over!<br>
					Score: <span id="finalScore">0</span><br>
					<a class="button" id="restart">Try Again!</a>
				</p>
			</div>
		</div>
	</body>
</html>

本文地址:https://blog.csdn.net/lishihuijava/article/details/107279551