JavaScript前端 制作2048游戏

2048是非常经典的数字游戏 今天给大家带来JavaScript版本

下面直接上代码重点位置在单独拿出来说 , 一共分为三部分


HTML部分

<a href="#">2048a> <input type="button" onclick="game.start()" value="Try Again" class="tryagain0"> h1>

score:<span id="score01">span> h1> div> <div class="game-message"> <p>Game Overp> <p>score:<span id="score02">span>p> <div class="button"> <input type="button" onclick="game.start()" value="Try Again" class="tryagain"> div> div> <div class="game-contain"> <div class="game-ex"> <div class="game-row"> <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>

代码不是完整的 header主要是游戏界面上方的一些图标和重新开始按钮以及一些你需要的文字部分 根据自己的喜好或者要求完成即可 , 下面的十六个方块都是一样的组成 当然也可以通过 ul - li 去布局

CSS部分
body{
	color: #776e65;
    font-family:Arial;
    font-size : 18px;
}
.contain{
	width : 500px;
	margin : 0 auto;
	display : block;
}
.game-contain{
	margin-top:25px;
    padding: 15px;
    background: #bbada0;
    border-radius: 6px;
    width: 500px;
    height: 500px;
    position:relative;
}
.cell{
	width: 106.25px;
    height: 106.25px;
    margin-right: 15px;
    float: left;
    border-radius: 10px;
    background: rgba(238, 228, 218, 0.35);
    margin-bottom:15px;
    text-align:center;
    line-height:2.5;
}
.game-message{
	display: none;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(238, 228, 218, 0.5);
    z-index: 100;
    text-align: center;
    padding-top:170px;
}

CSS 部分代码主要还是根据自己做的样式这里主要说一下 .game-message 的样式中 top , right , bottom , left 都设置为0 并把堆叠放置在最上层 主要是做一个遮罩层 当用户游戏结束后覆盖整个画面也是为了防止一些其他的操作只能点击返回

JavaScript部分

首先我们的编程都是面向对象的思想 所以我们整个JavaScript部分都是以 game 为一个对象 只是向他添加属性和方法

var game = {
	data: [],
	score: 0,
	gameover: 0,
	gameruning: 1,
	status: 1,
	start: function() {
		this.status = this.gameruning;
		this.data = [];
		for(var r = 0; r < 4; r++) {
			this.data[r] = [];
			for(var c = 0; c < 4; c++) {
				this.data[r][c] = 0;
			}
		}
		this.score = 0;
		this.randomNum();
		this.randomNum();
		this.displayData();
	},
	randomNum: function() {
		for(;;) {
			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.3 ? 2 : 4;
				this.data[r][c] = num;
				break;
			}
		}
	},
	displayData: function() {
		for(var r = 0; r < 4; r++) {
			for(var c = 0; c < 4; c++) {
				var div = document.getElementById("c" + r + c)
				if(this.data[r][c] == 0) {
					div.innerHTML = "";
					div.className = "cell";

				} else {
					div.innerHTML = this.data[r][c];
					div.className = "cell num" + this.data[r][c];

				}
			}
		}
		document.getElementById("score01").innerHTML = this.score;
		if(this.status == this.gameover) {
			document.getElementById("score02").innerHTML = this.score;
			document.getElementsByClassName("game-message")[0].style.display = "block"
		} else {
			document.getElementsByClassName("game-message")[0].style.display = "none"
		}
	},
	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;
	},
	//	向左
	moveLeft: function() {
		var before = this.data.toString();
		for(var r = 0; r < 4; r++) {
			this.leftRow(r);
		}
		var after = this.data.toString();
		if(before != after) {
			this.randomNum();
			if(this.isgameover()) {
				this.status = this.gameover;
			}
			this.displayData();
		}
	},
	leftRow: function(r) {
		for(var c = 0; c < 3; c++) {
			var nextc = this.leftNext(r, c);
			if(nextc == -1) {
				break;
			} else {
				if(this.data[r][c] == 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]) {
					this.data[r][c] *= 2;
					this.score += this.data[r][c] ;
					this.data[r][nextc] = 0;
				}
			}
		}
	},
	leftNext: function(r, c) {
		for(var nextc = c + 1; nextc < 4; nextc++) {
			if(this.data[r][nextc] != 0) {
				return nextc;
			}
		}
		return -1;
	},

	//向右
	moveRight: function() {
		var before = this.data.toString();
		for(var r = 0; r < 4; r++) {
			this.rightRow(r);
		}
		var after = this.data.toString();
		if(before != after) {
			this.randomNum()
			if(this.isgameover()) {
				this.status = this.gameover
			}
			this.displayData();
		}
	},
	rightRow: function(r) {
		for(var c = 3; c > 0; c--) {
			var rightc = this.rightNext(r, c);
			if(rightc == -1) {
				break;
			} else {
				if(this.data[r][c] == 0) {
					this.data[r][c] = this.data[r][rightc];
					this.data[r][rightc] = 0;
					c++;
				} else if(this.data[r][c] == this.data[r][rightc]) {
					this.data[r][c] *= 2;
					this.score += this.data[r][c] ;
					this.data[r][rightc] = 0;
				}
			}
		}
	},
	rightNext: function(r, c) {
		for(var rightc = c - 1; rightc >= 0; rightc--) {
			if(this.data[r][rightc] != 0) {
				return rightc;
			}
		}
		return -1;
	},
	//向下
	moveDown: function() {
		var before = this.data.toString();
		for(var c = 0; c < 4; c++) {
			this.downRow(c);
		}
		var after = this.data.toString();
		if(before != after) {
			this.randomNum()
			if(this.isgameover()) {
				this.status = this.gameover
			}
			this.displayData();
		}
	},
	downRow: function(c) {
		for(var r = 3; r > 0; r--) {
			var downr = this.downNext(r, c);
			if(downr == -1) {
				break;
			} else {
				if(this.data[r][c] == 0) {
					this.data[r][c] = this.data[downr][c];
					this.data[downr][c] = 0;
					r++;
				} else if(this.data[r][c] == this.data[downr][c]) {
					this.data[r][c] *= 2;
					this.score += this.data[r][c];
					this.data[downr][c] = 0;
				}
			}
		}
	},
	downNext: function(r, c) {
		for(var downr = r - 1; downr >= 0; downr--) {
			if(this.data[downr][c] != 0) {
				return downr;
			}
		}
		return -1;
	},
	//向上
	moveUp: function() {
		var before = this.data.toString();
		for(var c = 0; c < 4; c++) {
			this.upRow(c);
		}
		var after = this.data.toString();
		if(before != after) {
			this.randomNum()
			if(this.isgameover()) {
				this.status = this.gameover
			}
			this.displayData();
		}
	},
	upRow: function(c) {
		for(var r = 0; r < 3; r++) {
			var upr = this.upNext(r, c);
			if(upr == -1) {
				break;
			} else {
				if(this.data[r][c] == 0) {
					this.data[r][c] = this.data[upr][c];
					this.data[upr][c] = 0;
					r--;
				} else if(this.data[r][c] == this.data[upr][c]) {
					this.data[r][c] *= 2;
					this.score += this.data[r][c];
					this.data[upr][c] = 0;
				}
			}
		}
	},
	upNext: function(r, c) {
		for(var upr = r + 1; upr < 4; upr++) {
			if(this.data[upr][c] != 0) {
				return upr;
			}
		}
		return -1;
	},
}
document.onkeydown = function(e) {
	if(game.status == game.gameruning) {
		var e = window.event || arguments[0];
		var code = e.keyCode;
		if(code == 37) {
			game.moveLeft();
		} else if(code == 39) {
			game.moveRight();
		} else if(code == 38) {
			game.moveUp();
		} else if(code == 40) {
			game.moveDown();
		}
	}
}
var startX,startY,endX,endY;
document.addEventListener("touchstart",function(e){
	var e = event || arguments[0];
	startX = e.touches[0].pageX;
	startY = e.touches[0].pageY;
})
document.addEventListener("touchend",function(e){
	var e = event || arguments[0];
	endX = e.changedTouches[0].pageX;
	endY = e.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) {
		game.moveRight();
	}else if (x<0 && absX) {
		game.moveLeft();
	}else if (y>0 && absY) {
		game.moveDown();
	}else if (y<0 && absY) {
		game.moveUp();
	}
})
game.start()

讲解几个重要的函数 : randomNum 遍历判断某个位置是否有数字 没有则生成一个随机数 2和4 的比例一般设置在 7:3 ; displayData作为主函数 是更新显示HTML界面的方法这里的一个想法是通过拼凑字符串来获取我们HTML里的ID,避免了重复的代码量,并调用判断是否结束的函数来改变我们遮盖层的display属性 ; 然后是我们的方向移动函数 这里以向左为例:**moveLeft:**向左主函数循环每一排赋值给 leftRow 去在同一排往后寻找如果为0则替换 ,**这里注意C–**目的是再次循环当次数 避免同一排两个相同的左右数不能正常合并 ; 然后我们的 onkeydown 绑定键盘事件 到这里web版本的就已经完成了 , 下面的 addEventListener 事件监听器 绑定我们的手机触摸 可以制作我们的 Android 版本


如有错误,请指正!

你可能感兴趣的:(JavaScript前端 制作2048游戏)