HTML + CSS + JS 写出简单2048游戏

HTML + CSS + JS 写出简单2048游戏

在这里插入代码片
/*html 代码:*/

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>2048游戏</title>
		<style>
			.container{
				width: 600px;
				height: 600px;
				border: 2px solid #000;
				background-color: white;
				margin: auto;
			}

			.header{
				font: bold 40px arial;
				margin-left: 80px;
			}
			.header span, #gameOver span{
				color: red;
			}
			
			#gameBody{
				width: 450px;
				height: 450px;
				margin-left: 80px;
				padding: 5px 0 0 5px;
				border-radius: 10px;
				background-color: #bbada0;
			}
			
			.cell{
				width: 100px;
				height: 100px;
				margin: 5px;
				background-color: #ccc0b3;
				border-radius: 5px;
				float: left;
				font: 50px/100px arial;
				text-align: center;
			}
			
			.n2{background-color: #eee3da}
			.n4{background-color: #ede0c8}
			.n8{background-color: #f2b179}
			.n16{background-color: #f59563}
			.n32{background-color: #f67c5f}
			.n64{background-color: #f65e3b}
			.n128{background-color: #edcf72}
			.n256{background-color: #edcc61}
			.n512{background-color: #9c0}
			.n1024{background-color: #33b5e5}
			.n2048{background-color: #09c}
			.n4096{background-color: #a6c}
			.n8192{background-color: #93c}
			.n2,.n4{color: #776e65}
			.n1024,.n2048,.n4096,.n8192{font-size: 40px}
			
			
			#gameOver{
				display: none;
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				background:rgba(55,55,55,0.5);
			}
			
			#gameOver p{
				width: 300px;
				height: 200px;
				position: absolute;
				top: 50%;
				left: 50%;
				margin: -100px 0 0 -150px;
				text-align: center;
				border-radius: 10px;
				border: 1px solid #edcf72;
				font: bold 40px/65px arial;
				background: #fff;
			}
			
			#gameOver .btn{
				padding: 10px;
				color:#fff;
				background: #9f8d77;
				border-radius: 6px;
				text-decoration: none;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<p class="header">SCORE:<span id="score">0</span></p>
			<div id="gameBody">
						<div  class="cell" id="cell-00"></div>
						<div  class="cell" id="cell-01"></div>
						<div  class="cell" id="cell-02"></div>
						<div  class="cell" id="cell-03"></div>
						<div  class="cell" id="cell-10"></div>
						<div  class="cell" id="cell-11"></div>
						<div  class="cell" id="cell-12"></div>
						<div  class="cell" id="cell-13"></div>
						<div  class="cell" id="cell-20"></div>
						<div  class="cell" id="cell-21"></div>
						<div  class="cell" id="cell-22"></div>
						<div  class="cell" id="cell-23"></div>
						<div  class="cell" id="cell-30"></div>
						<div  class="cell" id="cell-31"></div>
						<div  class="cell" id="cell-32"></div>
						<div  class="cell" id="cell-33"></div>
			</div>
			<div id="gameOver">
				<p>
					GAME OVER<br>
					SCORE:<span id="final">0</span><br>
					<a href="javascript:game.start();" class="btn">TRY AGAIN!</a>
				</p>
			</div>
		</div>
		
		<script>
			//创建对象:属性+方法
			var game = {
				//数组,保存数据
				data:[],
				//游戏得分:0
				score:0,
				//设置游戏状态:1-开始,0-结束
				state:1,
				//游戏状态:开始
				RUNNING:1,
				//游戏状态:结束
				GAMEOVER:0,
				
				//游戏开始start()方法
				start:function(){
					//设置游戏状态为开始
					this.state=this.RUNNING;
					//初始化游戏得分为0
					this.score=0;
					//创建一个二维数组
					for(var r = 0; r < 4; r++){
						//创建一个一维数组,
						var datacell = [];
						//将一维数组值初始化为0
						for(var c = 0;c < 4; c++){
							datacell[c] = 0;
						}
						//将一维数组的值循环赋给数组data[],成功创建一个二维数组
						this.data[r] = datacell;
					}
					
					//调用函数随机生成两个数
					this.randomNum();
					this.randomNum();
					//刷新页面,显示div的值
					this.updateView();
				},
				
				//随机生成两个数4或2
				randomNum:function(){
					while(true){
						var r=Math.floor(Math.random()*this.data.length);
						var c=Math.floor(Math.random()*this.data.length);
						if(this.data[r][c]==0){
							//随机生成2和4的概率相等
							this.data[r][c]=Math.random()<0.5?2:4;
							break;
						}
					}
				},
				
				updateView:function(){
					for(var r=0;r<this.data.length;r++){
						for(var c=0;c<this.data.length;c++){
							//判断数组中的数据,为0则不做任何操作,保持原来数据和类名不变
							//动态获取标签的id:要求取id名时与数组下角标相对应
							if(this.data[r][c]==0){
								document.getElementById("cell-"+r+c).innerHTML="";
								document.getElementById("cell-"+r+c).className="cell";
							}else{
								//不为0,则将数组中数据显示在对应的div格子中
								document.getElementById("cell-"+r+c).innerHTML= this.data[r][c];
								//保持原来类名不变,并追加对应div类名(动态)
								document.getElementById("cell-"+r+c).className="cell n" + this.data[r][c];
								
							}
						}
					}
					//将分数显示在界面上方
					document.getElementById("score").innerHTML=this.score;
					var gameOver=document.getElementById("gameOver");
					if(this.state==this.GAMEOVER){
						//如果状态为GAMEOVER(即0,表示游戏结束,显示结束界面,并将最后分数显示在结束界面
						gameOver.style.display="block";
						document.getElementById("final").innerHTML=this.score;
					}else{
						//如果状态为1,表示游戏还未结束,隐藏结束界面
						gameOver.style.display="none";
					}
				},
				
				//向左移动所有行
				moveLeft:function(){
					//判断字符串是否移动
					//做移动操作前先将数组转换为字符串保存
					var before=String(this.data);
					//遍历行
					for(var r=0;r<this.data.length;r++){
						this.moveLeftRow(r);
					}
					//做移动操作后先将数组转换为字符串保存
					var after=String(this.data);
					//将移动操作前后的数组(字符串)作比较,如果不相等,即发生改变,则随机生成一个数
					if(before!=after){
						this.randomNum();
						//随机生成一个数后,判断游戏是否结束,设置游戏状态
						if(this.isGameOver()){
							this.state=this.GAMEOVER;
						}
						//游戏未结束刷新页面,再显示随机生成数
						this.updateView();
					}
				},
				
				//判断并向左移动指定行中的每个元素
				moveLeftRow:function(r){
					//0开始,遍历r行中每一个元素
					for(var c=0;c<this.data.length-1;c++){
						//获得当前元素下一个不为0的元素的下标nextc
						var nextc=this.getNextRow(r,c)
						//如果nextc=-1,说明右侧没有元素了,退出循环
						if(nextc==-1) {
							break;
						}else if(this.data[r][c]==0){   //如果自己==0 则将下一个位置放入当前位置,下一个位置设置为零
							this.data[r][c]=this.data[r][nextc];
							this.data[r][nextc]=0;
							//重新检查
							c--;
						}else if(this.data[r][c]==this.data[r][nextc]){// 如果当前位置的值==nextc的位置的值,将当前位置*=2;下一个位置设置为0
							this.data[r][c]*=2;
							//将当前值累加到score属性上
							this.score+=this.data[r][c];
							this.data[r][nextc]=0;
						}
					}
				},
				
				//找当前位置右侧,下一个不为0的数
				getNextRow:function(r,c){
					//从c+1 遍历row行中剩余元素,
					for(var i=c+1;i<this.data.length;i++){
						//如果出现不为0的值,返回它的列数
						if(this.data[r][i]!=0) {
							return i;
						}
					}
					//循环退出返回-1
					return -1;
				},
					
					
				//向右移动所有行	
				moveRight:function(){
					var before=String(this.data);
					for(var r=0;r<this.data.length;r++){
						this.moveRightRow(r);
					}
					var after=String(this.data);
					if(before!=after){
						this.randomNum();
						if(this.isGameOver()){
							this.state=this.GAMEOVER;
						}
						this.updateView();
					}
				},
			
				moveRightRow:function(r){
					for(var c=this.data.length-1;c>0;c--){
						var prec=this.getPreRow(r,c)
						if(prec==-1){
							break;
						}else if(this.data[r][c]==0){
							this.data[r][c]=this.data[r][prec];
							this.data[r][prec]=0;
							c++;
						}else if(this.data[r][c]==this.data[r][prec]){
							this.data[r][c]*=2;
							this.score+=this.data[r][c];
							this.data[r][prec]=0;
						}
					}
				},
				
				getPreRow:function(r,c){
					for(var i=c-1;i>=0;i--){
						if(this.data[r][i]!=0) return i;	
						}
						return -1;
				},
					
				moveUp:function(){
					var before=String(this.data);
					for(var c=0;c<this.data.length;c++){
						this.moveUpCol(c);
					}
					var after=String(this.data);
					if(before!=after){
						this.randomNum();
						if(this.isGameOver()){
							this.state=this.GAMEOVER;
						}
						this.updateView();
					}
				},
				
				//向上移动所有列
				moveUpCol:function(c){
					for(var r=0;r<this.data.length-1;r++){
						var nextr=this.getNextCol(r,c)
						if(nextr==-1) {break;
						}else if(this.data[r][c]==0){
							this.data[r][c]=this.data[nextr][c];
							this.data[nextr][c]=0;
							r--;
						}else if(this.data[r][c]==this.data[nextr][c]){
						this.data[r][c]*=2;
						this.score+=this.data[r][c];
						this.data[nextr][c]=0;
					}
					}
				},
					
				getNextCol:function(r,c){
					for(var i=r+1;i<this.data.length;i++){
						if(this.data[i][c]!=0) return i;	
					}
					return -1;
				},
				
				//向下移动所有列
				moveDown:function(){
					var before=String(this.data);
					for(var c=0;c<this.data.length;c++){
						this.moveDownCol(c);
					}
					var after=String(this.data);
					if(before!=after){
						this.randomNum();
						if(this.isGameOver()){
							this.state=this.GAMEOVER;
						}
						this.updateView();
					}
				},
				
				moveDownCol:function(c){
					for(var r=this.data.length-1;r>0;r--){
						var prer=this.getPreCol(r,c)
						if(prer==-1) {
							break;
						}
						else if(this.data[r][c]==0){
							this.data[r][c]=this.data[prer][c];
							this.data[prer][c]=0;
							r++;
						}else if(this.data[r][c]==this.data[prer][c]){
							this.data[r][c]*=2;
							this.score+=this.data[r][c];
							this.data[prer][c]=0;
						}
					}
				},
				
				getPreCol:function(r,c){
					for(var i=r-1;i>=0;i--){
						if(this.data[i][c]!=0) return i;	
					}
					return -1;
				},
				
				isGameOver:function(){
					//游戏结束条件:
					//1.数组中所有数据均不为0;
					//2.数组中每一行数据相邻位置值不相等
					//3.数组中每一列数据相邻位置值不相等
					for(var c=0;c<this.data.length;c++){
						for(var r=0;r<this.data.length;r++){
							//判断所有不为0
							if(this.data[r][c]==0){
								return false;
							}
							if(c<3){
								if(this.data[r][c]==this.data[r][c+1]){
									return false;
								}
							}
							if(r<3){
								if(this.data[r][c]==this.data[r+1][c]){
									return false;
								}
							}
						}
					}
					return true;
				}
			}
			
			//调用函数开始游戏
			game.start();
			document.onkeydown=function(event){
				//按下左键或者字母键a,向左移动
				if(event.keyCode==37 || event.keyCode==65 ){
					game.moveLeft();
				}
				//按下向上键或者字母键w,向上移动
				if(event.keyCode==38 || event.keyCode==87 ){
					game.moveUp();
				}
				//按下右键或者字母键d,向右移动
				if(event.keyCode==39 || event.keyCode==68 ){
					game.moveRight();
				}
				//按下向下键或者字母键s,向下移动
				if(event.keyCode==40 || event.keyCode==83 ){
					game.moveDown(); 
				}
				//按下空格键重新开始游戏
				if(event.keyCode==32 ){
					game.start();
				}
				
			}
			
		</script>
	</body>
</html>!

游戏开始界面
游戏结束界面

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值