原生JS+HTML表格Table实现2048小游戏

最近闷头学习JS,有些收获,闲着实现了个2048小游戏,废话不多说,直接看效果、代码。

 

 

效果图

原生JS+HTML表格Table实现2048小游戏_第1张图片

原生JS+HTML表格Table实现2048小游戏_第2张图片

1.思路

  1. 2048首先是一个4*4的16格棋盘,那么用表格还挺方便的,表格直接text-align就可以把文字左右、上下居中。
  2. 其次,每个格子块有自己的数字,那么就可以有一个格子块类Div,它有属性number,有方法is2048()判断是否通关,一个格子实例的数组就代表了16个格子。
  3. 我们可以通过监听键盘的onkeydown事件来判断格子块移动方向,百度得知←↑→↓键盘码分别为37、38、39、40,通过window.event.keyCode获得当前敲击键盘事件的键盘码。(这里有个小坑,onkeypress只能监听数字、字母键,所以不能通过它来监听up这样的功能键)
  4. 得到移动方向后,如果是左右那就是横向移动,为了简化操作,可以把格子数组按行(横行竖列)分割成4个格子数组,每个数组代表每一行的格子,对一行的所有格子遍历,非零格子向左或右移动,直到碰到另一个非零格子,上下操作则按列分割。(移动并不是td节点的移动,而是格子实例的number的变化)
  5. 因为移动是对格子实例的number的操作,所以页面并不会变化,就需要一个函数render()来更新页面,根据每个格子类的number依次对td节点的数字、背景颜色操作。

2.html以及css代码



	
		
		2048Game
		
	
	
		分数:0
		步数:0
		

3.js代码

  • 格子类model.js
function Div(id,number){
	this.id = id;//记录位置
	this.number = number;//没有块则为0
	if(this._initalized == undefined){
		//是否达到2024
		Div.prototype.is2024 = function(){
			if(this.number == 2024)
				return true;
			else
				return false;
		}
		this._initalized = true;
	}
}
  • 控制函数controll.js
var arr = init();
var isOver_row = false;
var isOver_col = false;
var score = 0;
var count = 0;
render();
function init() {
	//初始化游戏
	var divArr = [];
	var n = 16;
	for (var i = 0; i < n; i++) {
		divArr.push(new Div(i, 0));
		//console.log(divArr[i])
	}
	divArr[0].number = 4;
	divArr[15].number = 4;
	return divArr;
}

function moveControll() {
	var direction = event.keyCode;
	if(isOver_col && isOver_row){
		alert("GameOver!");
		return undefined;
	}
	if (direction == 37 || direction == 39) {
		isOver_row = !moveRow(direction);
	} else if (direction == 38 || direction == 40) {
		isOver_col = !moveCol(direction);
	}
}

function moveCol(direction) {
	//1.得到每一列的方块如cols[[0,4,8,12],[1,5,9,13],[2,6,10,14],[3,7,11,15]];
	var cols = [];
	for (var i = 0; i < 4; i++) {
		var col = [];
		for (var j = i; j < arr.length; j += 4) {
			col.push(arr[j]);
		}
		cols.push(col);
	}
	//2.方向分支
	if (direction == 38) {//如果键盘码为38,应该向上移动
		for (var i = 0; i < cols.length; i++) {//将所有非零块移动到最上端。
			for (var j = 0; j < cols[i].length - 1; j++) {
				if (cols[i][j].number == 0 && cols[i][j + 1].number != 0) {当该块数字为0且相邻方向为上的块数字不为0则将该块数字置为0,上一块置为数字*2
					cols[i][j].number = cols[i][j + 1].number;
					cols[i][j + 1].number = 0;
					j = -1;
				}
			}
		}
		for (var i = 0; i < cols.length; i++) {//将所有
			for (var j = 0; j < cols[i].length - 1; j++) {
				if (cols[i][j].number == cols[i][j + 1].number) {
					cols[i][j].number += cols[i][j + 1].number;
					score+=cols[i][j].number;
					cols[i][j + 1].number = 0;
				}
			}
		}
	} else {
		for (var i = 0; i < cols.length; i++) {
			for (var j = cols[i].length - 1; j >0 ; j--) {
				if (cols[i][j].number == 0 && cols[i][j - 1].number != 0) {
					cols[i][j].number = cols[i][j - 1].number;
					cols[i][j - 1].number = 0;
					j = cols[i].length;
				}
			}
		}
		for(var i = 0;i0;j--){
				if(cols[i][j].number == cols[i][j-1].number){
					cols[i][j].number +=cols[i][j-1].number;
					score+=cols[i][j].number;
					cols[i][j-1].number = 0;
				}
			}
		}
		
	}

	//4.如果棋盘未满,随机一格出现一个新方块
	if (!getNewDiv(arr)) {
		return false;
	}
	count++;//步数统计
	//5.渲染页面
	render();
	return true;
}

function moveRow(direction) {
	//1.得到每一行的方块
	var rows = [];
	for (var i = 0; i < 16; i+=4) {
		var row = [];
		for (var j = i; j < i+4; j++) {
			row.push(arr[j]);
		}
		rows.push(row);
	}
	console.log(rows);
	//2.方向分支
	if (direction == 37) {
		for (var i = 0; i < rows.length; i++) {
			for (var j = 0; j < rows[i].length - 1; j++) {
				if (rows[i][j].number == 0 && rows[i][j + 1].number != 0) {
					rows[i][j].number = rows[i][j + 1].number;
					rows[i][j + 1].number = 0;
					j = -1;
				}
			}
		}
		for (var i = 0; i < rows.length; i++) {
			for (var j = 0; j < rows[i].length - 1; j++) {
				if (rows[i][j].number == rows[i][j + 1].number) {
					rows[i][j].number += rows[i][j + 1].number;
					score+=rows[i][j].number;
					rows[i][j + 1].number = 0;
				}
			}
		}
	} else {
		for (var i = 0; i < rows.length; i++) {
			for (var j = rows[i].length - 1; j >0 ; j--) {
				if (rows[i][j].number == 0 && rows[i][j - 1].number != 0) {
					rows[i][j].number = rows[i][j - 1].number;
					rows[i][j - 1].number = 0;
					j = rows[i].length;
				}
			}
		}
		for(var i = 0;i0;j--){
				if(rows[i][j].number == rows[i][j-1].number){
					rows[i][j].number +=rows[i][j-1].number;
					score+=rows[i][j].number;
					rows[i][j-1].number = 0;
				}
			}
		}
		
	}
	if (!getNewDiv(arr)) {
		return false;
	}
	count++;
	//5.渲染页面
	render();
	return true;
}

function getNewDiv(arr) {
	var ids = [];
	for (var i = 0; i < arr.length; i++) {
		if (arr[i].number == 0) {
			ids.push(arr[i].id);
		}
	}
	if (ids.length == 0) {
		return false;
	}
	var id = ids[getRandom(ids.length, 0)];
	arr[id].number = 4;
	return true;
}

function getRandom(max, min) {
	return Math.floor(Math.random() * (max - min) + min);
}

function render() {
	var span1 = document.getElementById("span_1");
	var span2 = document.getElementById("span_2");
	span1.innerText = score;
	span2.innerText = count;
	//根据number渲染每个td元素
	var cells = document.getElementsByTagName("td");
	var color;
	for (var i = 0; i < cells.length; i++) {
		switch (arr[i].number) {
			case 4:
				color = "coral";
				break;
			case 8:
				color = "#CCFF99";
				break;
			case 16:
				color = "#99CCFF";
				break;
			case 32:
				color = "#CCCCFF";
				break;
			case 64:
				color = "#009966";
				break;
			case 128:
				color = "#CCFF00";
				break;
			case 256:
				color = "#CC0033";
				break;
			case 512:
				color = "black";
				break;
			case 1024:
				color = "blue";
				break;
			case 2048:
				color = "green";
				break;
			default:
				color = "#fff";
		}
		cells[i].style.backgroundColor = color;
		cells[i].innerText = arr[i].number != 0 ? arr[i].number : "";
	}
	
}

 

你可能感兴趣的:(前端实例,2048,原生js,table,源代码)