JavaScript实现2048小游戏

闲着没事干敲的,属实是有点闲。(听君一席话,如听一席话。
<!-- Author: LQQ -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
*{
margin:0;
padding:0;
}
table{
width:500px;
height:500px;
margin:60px auto;
position:relative;
background-color:pink;
border:0px solid purple;
color:	#778899;
}
td{
width:125px;
height:125px;
text-align:center;
border-radius: 10px;
}

</style>
</head>
<body>
<table class="table">
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</table>
<div><div>
<script >

//初始化阶段
let a = new Array(4);//初始化4行的二维数组
let tds = new Array(4);
let b = new Array(4);//来一个备用数组,比较移动前后,数组是否有变换
let tr_tds = document.querySelectorAll("td");
for(let i = 0;i < 4;i++){
	a[i] = new Array(4);//初始化每行有4列
	tds[i] = new Array(4);
	b[i] = new Array(4);
}
for(let i = 0,cnt = 0;i < 4;i++){//初始化每个放个里面的数字为0
	for(let j = 0;j < 4;j++){
		a[i][j] = 0;
		tds[i][j] = tr_tds[cnt];
		cnt++;
	}
}
rand_create();
num_to_HTML();
changestyle();


//开始运行阶段
document.onkeydown = function(e){
	let flag = true;
	copy_a();
	if(e.key === "ArrowUp" || e.key === "w" || e.key === "W"){
		changeup();
		mergeup();
	}else if(e.key === "ArrowDown" || e.key === "s" || e.key === "S"){
		changedown();
		mergedown();
	}else if(e.key === "ArrowLeft" || e.key === "a" || e.key === "A"){
		changeleft();
		mergeleft();
	}else if(e.key === "ArrowRight" || e.key === "d" || e.key === "D"){
		changeright();
		mergeright();
	}
	if(compare()){
		flag = rand_create();
		num_to_HTML();
		changestyle();
	}
	if(rand_create() === false && isfail() === false){
		setTimeout(function(){
			alert("寄,你是真的菜.");
		},1000);
	}
}



//函数化阶段
function rand_create_num(Size){//生成一个(0 ~ Size - 1)的随机数字
	let n = Size * Math.random();
	let m = Math.floor(n);
	return m;
}
function rand_create_tow_or_four(){//随机返回数字4或者2,这里可以调节数字生成的概率,进而改变游戏的难度
	let n = rand_create_num(4);
	if(n < 1) return 2;
	else return 4;
}
function rand_create(){//寻找一个值为零的地方作为随机生成数的地方。//操作成功返回true,否则返回false  
	let arr_r = new Array();//储存值为0的二维数组的行
	let arr_c = new Array();//储存值为0的二维数组的列
	let cnt = 0;//下标从0开始
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			if(a[i][j] === 0){
				arr_r[cnt] = i;
				arr_c[cnt] = j;
				cnt++;//下标加一
			}
		}
	}
	if(cnt === 0){
		return false;
	}
	let n = rand_create_num(cnt);
	a[arr_r[n]][arr_c[n]] = rand_create_tow_or_four();
	return true;
}
function num_to_HTML(){
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			if(a[i][j] === 0){
				tds[i][j].innerHTML = "";
			}else{
				tds[i][j].innerHTML = a[i][j];
			}
		}
	}
}
function copy_a(){
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			b[i][j] = a[i][j];
		}
	}
}
function compare(){
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			if(a[i][j] !== b[i][j]) return true;
		}
	}return false;
}
function changestyle(){
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			Selecte_font_and_color(i,j);
		}
	}
}
function isfail(){
	for(let i = 0;i < 4;i++){
		for(let j = 0;j < 4;j++){
			let r = i + 1;
			let c = j + 1;
			if(r < 4 && a[i][j] === a[r][j]) return true;
			if(c < 4 && a[i][j] === a[i][c]) return true;
		}
	}return false;
}
function Selecte_font_and_color(r,c){//根据数字值的大小选择字体颜色,字体大小,背景颜色;随便在HTML中修改完成
	if(a[r][c] === 2){
		tds[r][c].style.fontSize = "60px";
		tds[r][c].style.backgroundColor = "#FFFAF0";
	}else if(a[r][c] === 4){
		tds[r][c].style.fontSize = "60px";
		tds[r][c].style.backgroundColor = "#FFF5EE";
	}else if(a[r][c] === 8){
		tds[r][c].style.fontSize = "60px";
		tds[r][c].style.backgroundColor = "#FFE4C4";
	}else if(a[r][c] === 16){
		tds[r][c].style.fontSize = "55px";
		tds[r][c].style.backgroundColor = "#F5DEB3";
	}else if(a[r][c] === 32){
		tds[r][c].style.fontSize = "55px";
		tds[r][c].style.backgroundColor = "#D2B48C";
	}else if(a[r][c] === 64){
		tds[r][c].style.fontSize = "55px";
		tds[r][c].style.backgroundColor = "#F4A460";
	}else if(a[r][c] === 128){
		tds[r][c].style.fontSize = "50px";
		tds[r][c].style.backgroundColor = "#FF7F50";
	}else if(a[r][c] === 256){
		tds[r][c].style.fontSize = "50px";
		tds[r][c].style.backgroundColor = "#FA8072";
	}else if(a[r][c] === 512){
		tds[r][c].style.fontSize = "50px";
		tds[r][c].style.backgroundColor = "#FF4500";
	}else if(a[r][c] === 1024){
		tds[r][c].style.fontSize = "45px";
		tds[r][c].style.backgroundColor = "#D2691E";
	}else if(a[r][c] === 2048){
		tds[r][c].style.fontSize = "45px";
		tds[r][c].style.backgroundColor = "#8B4513";
	}else if(a[r][c] === 4096){
		tds[r][c].style.fontSize = "45px";
		tds[r][c].style.backgroundColor = "#FF1493";
	}else if(a[r][c] === 8192){
		tds[r][c].style.fontSize = "45px";
		tds[r][c].style.backgroundColor = "#DC143C";
	}else{
		tds[r][c].style.backgroundColor = "skyblue";
	}
}
function changeup(){//移动函数
	for(let i = 0;i < 4;i++){//把数字集中到一起,方便后面的枚举。
		let arr = new Array();
		let cnt = -1;
		for(let j = 0;j < 4;j++){
			if(a[j][i] !== 0){
				arr[++cnt] = a[j][i];
			}
		}
		for(let j = 0;j < 4;j++){
			if(j <= cnt){
				a[j][i] = arr[j];
			}else{
				a[j][i] = 0;
			}
		}
	}
}
function changedown(){
	for(let i = 0;i < 4;i++){
		let arr = new Array();
		let cnt = -1;
		for(let j = 3;j >= 0;j--){
			if(a[j][i] !== 0){
				arr[++cnt] = a[j][i];
			}
		}
		for(let j = 3,l = 0;j >= 0;l++,j--){
			if(l <= cnt){
				a[j][i] = arr[l];
			}else{
				a[j][i] = 0;
			}
		}
	}
}
function changeleft(){
	for(let i = 0;i < 4;i++){
		let arr = new Array();
		let cnt = -1;
		for(let j = 0;j < 4;j++){
			if(a[i][j] !== 0){
				arr[++cnt] = a[i][j];
			}
		}
		for(let j = 0;j < 4;j++){
			if(j <= cnt){
				a[i][j] = arr[j];
			}else{
				a[i][j] = 0;
			}
		}
	}
}
function changeright(){
	for(let i = 0;i < 4;i++){
		let arr = new Array();
		let cnt = -1;
		for(let j = 3;j >= 0;j--){
			if(a[i][j] !== 0){
				arr[++cnt] = a[i][j];
			}
		}
		for(let j = 3,l = 0;j >= 0;l++,j--){
			if(l <= cnt){
				a[i][j] = arr[l];
			}else{
				a[i][j] = 0;
			}
		}
	}
}

function mergeup(){//合并移动方向上相同且相邻的数字//别忘了合并顺序上面的优先级
	for(let i = 0;i < 4;i++){
		if(a[0][i] === a[1][i] && a[2][i] === a[3][i]){
			a[0][i] = a[0][i] * 2;
			a[1][i] = a[2][i] * 2;
			a[2][i] = 0;
			a[3][i] = 0;
		}else if(a[0][i] === a[1][i]){
			a[0][i] = a[0][i] * 2;
			a[1][i] = a[2][i];
			a[2][i] = a[3][i];
			a[3][i] = 0;
		}else if(a[1][i] === a[2][i]){
			a[1][i] = a[1][i] * 2;
			a[2][i] = a[3][i];
			a[3][i] = 0;
		}else if(a[2][i] === a[3][i]){
			a[2][i] = a[2][i] * 2;
			a[3][i] = 0;
		}//移动方向上没有相同且相邻数字的就不移动,也就是不操作
	}
}
function mergedown(){
	for(let i = 0;i < 4;i++){
		if(a[3][i] === a[2][i] && a[1][i] === a[0][i]){
			a[3][i] = a[3][i] * 2;
			a[2][i] = a[1][i] * 2;
			a[1][i] = 0;
			a[0][i] = 0;
		}else if(a[3][i] === a[2][i]){
			a[3][i] = a[3][i] * 2;
			a[2][i] = a[1][i];
			a[1][i] = a[0][i];
			a[0][i] = 0;
		}else if(a[2][i] === a[1][i]){
			a[2][i] = a[2][i] * 2;
			a[1][i] = a[0][i];
			a[0][i] = 0;
		}else if(a[1][i] === a[0][i]){
			a[1][i] = a[1][i] * 2;
			a[0][i] = 0;
		}
	}
}
function mergeleft(){
	for(let i = 0;i < 4;i++){
		if(a[i][0] === a[i][1] && a[i][2] === a[i][3]){
			a[i][0] = a[i][0] * 2;
			a[i][1] = a[i][2] * 2;
			a[i][2] = 0;
			a[i][3] = 0;
		}else if(a[i][0] === a[i][1]){
			a[i][0] = a[i][0] * 2;
			a[i][1] = a[i][2];
			a[i][2] = a[i][3];
			a[i][3] = 0;
		}else if(a[i][1] === a[i][2]){
			a[i][1] = a[i][1] * 2;
			a[i][2] = a[i][3];
			a[i][3] = 0;
		}else if(a[i][2] === a[i][3]){
			a[i][2] = a[i][2] * 2;
			a[i][3] = 0;
		}
	}
}
function mergeright(){
	for(let i = 0;i < 4;i++){
		if(a[i][3] === a[i][2] && a[i][1] === a[i][0]){
			a[i][3] = a[i][3] * 2;
			a[i][2] = a[i][1] * 2;
			a[i][1] = 0;
			a[i][0] = 0;
		}else if(a[i][3] === a[i][2]){
			a[i][3] = a[i][3] * 2;
			a[i][2] = a[i][1];
			a[i][1] = a[i][0];
			a[i][0] = 0;
		}else if(a[i][2] === a[i][1]){
			a[i][2] = a[i][2] * 2;
			a[i][1] = a[i][0];
			a[i][0] = 0;
		}else if(a[i][1] === a[i][0]){
			a[i][1] = a[i][1] * 2;
			a[i][0] = 0;
		}
	}
}
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值