首先我们构建前台页面,该页面上有按钮,和16个放格,每个放格不同的样式
/*设置不同数字的颜色*/
#active2{color: #776e65;background-color: #eee4da;}
#active4{color: #776e65;background-color: #ede0c8;}
#active8{color: #f9f6f2;background-color: #f2b179;}
#active16{color: #f9f6f2;background-color: #f59563;}
#active32{color: #f9f6f2;background-color: #f67c5f;}
#active64{color: #f9f6f2;background-color: #f65e3b;}
#active128{color: #f9f6f2;background-color: #edcf72;}
#active256{color: #f9f6f2;background-color: #edcc61;}
#active512{color: #f9f6f2;background-color: #edc850;}
#active1024{color: #f9f6f2;background-color: #edc53f;}
#active2048{color: #f9f6f2;background-color: #edc22e;}
我们采用面对对象的思想来构建这个游戏逻辑,首先定义一个游戏类,里面存在游戏数据(data),游戏行数和列数(RN,CN),当前得分(score),最高成绩(best)等
var game = {
data:null, // 存储数据的二维数组
RN:4,CN:4, // 总行数 总列数
score:0,// 当前得分
best:0,// 最高成绩
star(){// 游戏初始化的方法},
getRdo(){// 取随机数的方法},
updateview(){// 更新页面视图的方法},
monitor(){// 键盘监控事件},
}
star(){
this.isstar = true;
// 创建一个RN*CN的二维数据,默认值为0
this.data = new Array();
for (var r = 0; r < this.RN; r++) {
this.data[r] = new Array();
for (var c = 0; c < this.CN; c++) {
this.data[r][c] = 0;
document.getElementById('c'+r+c).innerHTML = ' ';
}
}
// 随机两个位置生成随机两个数2或者4
this.getRdo();
this.getRdo();
// 初始化游戏得分
this.score = 0;
// 更新游戏视图
this.updeteview();
// 监听键盘按下事件
this.monitor();
}
getRdo(){
// 当前位置不为空是死循环,知道生成随机数跳出循环
while(true){
// 随机行数
var r = Math.floor(Math.random() * this.RN);
// 随机列数
var c = Math.floor(Math.random() * this.CN);
// 判断当前位置是否为空
if (this.data[r][c] == 0) {
// 写入数据取随机数写入2或者4
this.data[r][c] = Math.random() < 0.95? 2:4;
break;
}
}
}
monitor(){
document.onkeydown=function(event){
var e = event || window.event || arguments.callee.caller.arguments[0];
//38=上键,37=左键 40=下键,39=右键
if (this.isstar) {
if(e && e.keyCode==38){
this.setup();
}
if(e && e.keyCode==40){
this.setdown();
}
if(e && e.keyCode==37){
this.setleft();
}
if (e && e.keyCode==39) {
this.setrigth();
}
}
}.bind(this);
}
updeteview(){ // 更新页面
for (var r = 0;r < this.RN; r++) {
for (var c = 0; c < this.CN; c++) {
// 找到元素
var cell = document.getElementById('c'+r+c);
// 找到存在不等于0的值
if (this.data[r][c] != 0) { // 追加属性样式
cell.innerHTML = '' + this.data[r][c] + '';
}
else{ //清除属性样式
cell.innerHTML = '';
}
}
}
// 判断当前得分是否为最高得分
if (this.score > this.best) {
this.best = this.score;
}
// 更新当前得分和最高得分
document.getElementById('scorenum').innerHTML = this.score;
document.getElementById('bestnum').innerHTML = this.best;
}
setup(){ // 操作 上
var arr1 = String(this.data);
// 判断行数
for (var c = 0;c < this.CN;c++) {
// 从当前行数第一个开始循环
for (var r = 0;r < this.RN-1; r++) {
// 定义next
var next = -1;
// 查找当前的下一个是否为0
for (var i = r+1; i < this.RN; i++) {
// 如果不为0,则记录当前位置,跳出循环
if(this.data[i][c] != 0){
next = i;
break;
}
}
// 如果 当前位置为-1,则说明后面为空,则
if (next != -1) {
// 当前位置为0 则记录值得位置向前不为
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[i][c];
this.data[i][c] = 0;
r--;
}
// 如果两值相等,则合成
else if(this.data[r][c] == this.data[i][c]){
this.data[r][c] *= 2;
this.data[i][c] = 0;
this.score += this.data[r][c];
}
}
else{
break;
}
}
}
// 判断游戏是否结束
this.conlog(arr1);
}
IsNull(){
// 遍历数组
for (var i = 0;i < 4;i++) {
for (var j = 0;j < 4;j++) {
// 如果为空,则游戏继续
if (this.data[i][j] == 0) {
return false;
}
// 如果在第一列则判断右方的值是否相同
if (j < this.CN - 1) {
// 存在相同,游戏继续
if (this.data[i][j] == this.data[i][j+1]) {
return false
}
}
// 如果在第一行则判断下方的值是否相同
if (i < this.RN-1) {
if (this.data[i][j] == this.data[i+1][j]) {
return false;
}
}
}
}
// 如果都不存在 则放回游戏失败
return true;
}
win(){
// 遍历数组
for (var i = 0;i<4;i++) {
for (var j = 0;j < 4;j++) {
// 如果存在2048 则游戏胜利
if (this.data[i][j] == 2048) {
this.isstar = false;
return false;
}
}
}
}
conlog(arr1){
this.updeteview();
var newarr = String(this.data);
if (newarr != arr1) {
this.getRdo();
// 延时追加
setTimeout(function(){
this.updeteview();
}.bind(this),100);
}
// 不存在可操作函数时结束游戏
if(this.IsNull() == true){
document.getElementById('overgame').style.display = 'block';
this.isstar = false;
}
// 游戏胜利
if (this.win == false) {
document.getElementById('overgame').style.display = 'block';
document.getElementById('win').innerHTML = 'Game Victory!'
}
// 输出游戏
console.log(`${this.data.join('\n')}`);
}