CSS Mini Game 2048—Simple Mini Game Programming Just Have a Hand~ Can you play it? Can you write?

Simple realization of 2048 mini games

 

When you want to achieve 2048 game writing code, you can divide it into three steps

1. HTML part

First write HTML to build the game structure

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
<!--最外部的大框-->
<div class="outermost"> //包裹游戏全局的大盒子
    <!--title-->
    <span class="top"><b>SCORE:<span id="score01"></span></b></span>//顶部实时显示的游戏分数
    <!--游戏大框框-->
    <div class="big">//2048游戏为四行四列因此需要16个div盒子
        <div class="cell" id="c00"></div>
        <div class="cell" id="c01"></div>
        <div class="cell" id="c02"></div>
        <div class="cell" id="c03"></div>

        <div class="cell" id="c10"></div>
        <div class="cell" id="c11"></div>
        <div class="cell" id="c12"></div>
        <div class="cell" id="c13"></div>

        <div class="cell" id="c20"></div>
        <div class="cell" id="c21"></div>
        <div class="cell" id="c22"></div>
        <div class="cell" id="c23"></div>

        <div class="cell" id="c30"></div>
        <div class="cell" id="c31"></div>
        <div class="cell" id="c32"></div>
        <div class="cell" id="c33"></div>
    //游戏结束时会弹出的提示框
    </div>
    <!--提示框-->
    <div class="tips" id="gameover">
       <p>GAME OVER!!! <br>
           SCORE: <span id="score02">0</span><br>
           <button class="startbtn">重新开始</button>
       </p>
    </div>
    <!--重玩一遍-->
    <div class="foot">
        <button class="replay"><a>重玩一遍</a></button>
    </div>
</div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
复制代码

Two, css part

After the first step of building the game framework, the second step is to add styles to the game so that it can be displayed

*{
    padding: 0px;
    margin: 0px auto;
    font-family: Arial;

}
/*最外部的大框*/
.outermost{
    width: 480px;
    height: 600px;
    font-size: 40px;
    margin-top: 120px;
}
/*title*/
<!--顶部显示分数的样式-->
.top{
    margin: auto;
}
.top span{
    color: red;
}
/*游戏大框框*/
.big{
    width: 480px;
    height: 480px;
    background:pink;
    border-radius: 8px;
}
<!--给每一个盒子包裹的小框子添加样式-->
.cell{
    list-style: none;
    float: left;
    display: inline-block;
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    background-color: #fbf8cd;
    margin-left: 16px;
    margin-top: 16px;
    border-radius: 6px;
}
<!--提前把出现的数2、4、8、16等的数所在的格子给添加好样式增加游戏体验感-->
.n2{background-color:#f65e3b;color:#776e65}
.n4{background-color:#33b5e5;color:#776e65}
.n8{background-color:#f2b179;color:#776e65}
.n16{background-color:#f59563;color:#776e65}
.n32{background-color:#f67c5f;color:#776e65}
.n64{background-color:#f65e3b;color:#776e65}
.n128{background-color:#edcf72;color:#776e65}
.n256{background-color:#edcc61;color:#776e65}
.n512{background-color:#9c0;color:#776e65}
.n1024{background-color:#33b5e5;color:#776e65;font-size:40px}
.n2048{background-color:#09c;color:#776e65;font-size:40px}
/*提示框样式*/
.tips{
    border: 1px solid #cccccc;
    background: #FFFFFF;
    width: 400px;
    height: 200px;
    border-radius: 10px;
    color: #ff4456;
    text-align: center;
    line-height: 60px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -200px;
    margin-top: -100px;
    display: none;
}
.tips .startbtn{
    height: 50px;
    width: 200px;
    color: #FFFFFF;
    font-size: 20px;
    line-height: 50px;
    border-radius: 10px;
    background: cornflowerblue;
    border: none;
}
/*重玩一遍*/
.foot{
    width: 200px;
    height: 50px;
}
.foot>.replay{
    width: 200px;
    height: 50px;
    background: aquamarine;
    margin-top: 60px;
    color: lightpink;
    border:0;
    font-size: 24px;
    font-weight: bold;
    border-radius: 6px;
}
复制代码

After the HTML+CSS part of the game is written, the appearance of the game will come out, as shown in the following figure:

 

 

Three, JS part

Here comes the last and most critical step-add behavior, that is, the writing of the JS part, and add effects to it

//创建一个对象,里面存储所有的游戏数据及游戏方法
var game = {
	data : [],   //定义一个数组,用来存所有的游戏的数据
	score : 0,   //定义一个分数的属性
	gamerunning : 1,   //定义一个游戏运行的状态,将其设置为1与其他状态区分开
	gameover : 0,     //定义一个游戏结束的状态
	status : 0,      //这个是目前游戏的状态,时刻的跟上面两个状态做比较,确定游戏处于运行或者结束
	start : function(){   //游戏开始时候的方法
//		游戏开始的时候肯定是要把游戏的状态设置成游戏运行的状态
//		this == game
		this.status = this.gamerunning;
//		游戏开始的时候分数清空
		this.score = 0;
//		数组中的所有元素全部设置成0
		this.data = [
			[0,0,0,0],
			[0,0,0,0],
			[0,0,0,0],
			[0,0,0,0]
		];
		this.randomNum();//调用下面自定义的随机函数,可以在移动和开始的时候随机出来一个数
		this.randomNum();//调用两次是因为这是游戏开始时的方法,开局随机出现两个数和位置,因此需要调用两次
		this.dataView();//调用下面所写的更新视图的方法
	},
	
	
复制代码
//	随机数的函数,开始的时候随机生成,移动的时候随机生成
	randomNum: function(){
		while(true){
			//		随机生成行和列 0 - 3随机整数
			var r = Math.floor( Math.random() * 4 );   //随机生成一个行
			var c = Math.floor( Math.random() * 4 );   //随机生成一个列
			
			if(this.data[r][c] == 0){
				var num = Math.random() > 0.5 ? 2 : 4;//随机出现2或4
				this.data[r][c] = num;
				break;
			}
		}
	},
	
复制代码
//	更新试图的方法
	dataView: function(){
//		大的循环,然后把所有的元素全部遍历一遍
		for(var r = 0; r < 4; r++){
			for(var c = 0; c < 4; c++){
//				找到对应的div
				var div = document.getElementById("c" + r + c);  //字符串拼接
				if(this.data[r][c] != 0){
//					数组中对应的内容放到格子上面去
					div.innerHTML = this.data[r][c];
//					样式也写成对应的
					div.className = "cell n" + this.data[r][c];
				}else{
					div.innerHTML = "";
					div.className = "cell"
				}
			}
		}
		
复制代码
//		更新分数
		document.getElementById("score01").innerHTML = this.score;
		//游戏没有结束的时候 弹出层时刻都是隐藏的
		if(this.status == this.gamerunning){
			document.getElementById("gameover").style.display = "none";
		}else{
			document.getElementById("gameover").style.display = "block";
			document.getElementById("score02").innerHTML = this.score;
		}
	},
	
复制代码
//	判断游戏是否结束的方法
	isgameover: function(){
		for(var r = 0; r < 4; r++){
			for(var c = 0; c < 4; c++){
				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;
	},
	
复制代码

//The method of moving, the left, right, up and down four parts

	
//	左 右 上 下
//	左移的方法
	moveLeft: function(){
		var before = String(this.data);   //之前做一次转换
//		具体的移动需要处理的逻辑,直接处理好每一行即可
		for(var r = 0;r < 4;r ++){
			this.moveLeftInRow(r);
		}
		var after = String(this.data);  //移动之后再做一次转换
//		如果说移动之前不等于移动之后,肯定是发生了移动
		if(before != after){
			this.randomNum();   //生成随机数
//			生成的随机数可能会造成游戏的gameover
			if(this.isgameover()){
//				改变游戏的状态
				this.status = this.gameover
			}
//			更新视图
			this.dataView();
		}
	},
	moveLeftInRow: function(r){   //只去做处理每一行的逻辑
		for(var c = 0; c < 3; c++){
			var nextc = this.getNextinRow(r,c);
			if(nextc != -1){
				if(this.data[r][c] == 0){
//					如果等于0,直接替换
					this.data[r][c] = this.data[r][nextc];
					this.data[r][nextc] = 0;  //位置恢复成0
					c --;   //要让位置恢复到原地
				}else if(this.data[r][c] == this.data[r][nextc]){
					this.data[r][c] *= 2;   //位置直接翻一倍
					this.data[r][nextc] = 0;
					this.score += this.data[r][c];  //更新分数
				}
			}else{   //没有找到
				break;   //直接退出循环
			}
		}
	},
	getNextinRow: function(r,c){
		for(var i = c + 1; i < 4; i++){
			if(this.data[r][i] != 0){
				return i;    //表示已经找到位置,并且把位置返回出来
			}
		}
		return -1;   //返回一个标识符
	},
//	右移的方法
	moveRight: function(){
		var before = String(this.data);
		for(var r = 0; r < 4; r++){
			this.moveRightInRow(r);
		}
		var after = String(this.data);
		if(before != after){
			this.randomNum();
			if(this.isgameover()){
				this.status = this.gameover;
			}
			this.dataView();
		}
	},
	moveRightInRow: function(r){
		for(var c = 4; c > 0; c--){
			var prevc = this.getPrevInRow(r,c);
			if(prevc != -1){
				if(this.data[r][c] == 0){
					this.data[r][c] = this.data[r][prevc];
					this.data[r][prevc] = 0;
					c ++
				}else if(this.data[r][c] == this.data[r][prevc]){
					this.data[r][c] *= 2;
					this.data[r][prevc] = 0;
					this.score += this.data[r][c];
				}
			}else{
				break;
			}
		}
	},
	getPrevInRow: 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 < 4; c++){
			this.moveUpInCol(c);
		}
		var after = String(this.data);
		if(before != after){
			this.randomNum();
			if(this.isgameover()){
				this.status = this.gameover;
			}
			this.dataView();
		}
	},
	moveUpInCol: function(c){
		for(var r = 0;r < 4; r++){
			var nextr = this.getNextInCol(r,c);
			if(nextr != -1){
				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.data[nextr][c] = 0;
					this.score += this.data[r][c];
				}
			}else{
				break;
			}
		}
	},
	getNextInCol: function(r,c){
		for(var i = r + 1; i < 4; i++){
			if(this.data[i][c] != 0){
				return i;
			}
		}
		return -1;
	},
//	下移的方法
	moveDown: function(){
		var before = String(this.data);
		for(var c = 0;c < 4; c++){
			this.moveDownInCol(c);
		}
		var after = String(this.data);
		if(before != after){
			this.randomNum();
			if(this.isgameover()){
				this.status = this.gameover;
			}
			this.dataView();
		}
	},
	moveDownInCol: function(c){
		for(var r = 3; r > 0; r--){
			var prev = this.getPrevIncol(r,c);
			if(prev != -1){
				if(this.data[r][c] == 0){
					this.data[r][c] = this.data[prev][c];
					this.data[prev][c] = 0;
					r -- ;
				}else if(this.data[r][c] == this.data[prev][c]){
					this.data[r][c] *= 2;
					this.data[prev][c] = 0;
					this.score += this.data[r][c];
				}
			}else{
				break;
			}
		}
	},
	getPrevIncol: function(r,c){
		for(var i = r - 1; i >= 0; i--){
			if(this.data[i][c] != 0){
				return i;
			}
		}
		return -1;
	},
	
	
	
}
game.start();
console.log(game.data)
console.log(game.status);
console.log(game.score);
//键盘事件
document.onkeydown = function(){
	if(event.keyCode == 37){
		//console.log("左")
		game.moveLeft();
	}else if(event.keyCode == 38){
		//console.log("上")
		game.moveUp()
	}else if(event.keyCode == 39){
		//console.log("右")
		game.moveRight()
	}else if(event.keyCode == 40){
		//console.log("下")
		game.moveDown()
	}
}
//touch事件
//手指按下
var startX;//设定开始起始位置的x坐标
var startY;//设定开始起始位置的y坐标
var endX;//设定结束滑动位置的x坐标
var endY;//设定结束滑动位置的y坐标
document.addEventListener('touchstart',function(){
//	console.log("手指按下了屏幕")
	console.log(event);
	startX = event.touches[0].pageX;
	startY = event.touches[0].pageY;
})
//手指移动
//document.addEventListener('touchmove',function(){
//	console.log("手指的移动")
//})
//手指松开
document.addEventListener("touchend",function(){
//	console.log("手指松开")
	console.log(event);
	endX = event.changedTouches[0].pageX;//如何获取结束时的位置x
	endY = event.changedTouches[0].pageY;
	var X = endX - startX;
	var Y = endY - startY
	var absX = Math.abs(X) > Math.abs(Y);
	var absY = Math.abs(Y) > Math.abs(X);
	if(X > 0 && absX){
		console.log("右滑动")
		game.moveRight()
	}else if(X < 0 && absX){
		console.log("左滑动")
		game.moveLeft()
	}if(Y > 0 && absY){
		console.log("下滑动")
		game.moveDown()
	}if(Y < 0 && absY){
		console.log("上滑动")
		game.moveUp()
	}
})

复制代码

The following is the game rendering

 

 

 

Just like this, a simple 2048 game is complete

 

At last

Thank you very much for seeing here~

If you need these materials, you can click here to get them!

Guess you like

Origin blog.csdn.net/PC_372/article/details/114393109