您的位置:首页 > Web前端 > JavaScript

原生Js实现2048小游戏

2019-06-24 12:46 344 查看

介绍:

2048是几年之前之前挺火的一个小游戏,相比于上一个十滴水小游戏,实现要简单很多,网上也有很多思路,本文是参考妙味课堂的实现。

具体实现

首先,写好界面,效果如下:

  • 当按下方向键时,需要根据不同的方向来进行各行各列的运算,例如向右,则为1234块运算,5678块运算,如果向下,则为1,5,9,13块运算:

    因此需要有一个判断方向键,指定运算规则的函数:
document.onkeydown = function (e) {

switch (e.keyCode){
case 37:
// console.log('left');
run([0,1,2,3]);
run([4,5,6,7]);
run([8,9,10,11]);
run([12,13,14,15]);
break;
case 38:
// console.log('up');
run([0,4,8,12]);
run([1,5,9,13]);
run([2,6,10,14]);
run([3,7,11,15]);
break;
case 39:
// console.log('right');
run([0,1,2,3].reverse());
run([4,5,6,7].reverse());
run([8,9,10,11].reverse());
run([12,13,14,15].reverse());
break;
case 40:
// console.log('down');
run([0,4,8,12].reverse());
run([1,5,9,13].reverse());
run([2,6,10,14].reverse());
run([3,7,11,15].reverse());
break;

}
};
  • 而块之间的运算,需要检测他们的数值是否相同,如果相同则合并,可以通过数组处理,例如按下“←”后:
[2,2,2,2] => [4,4,0,0]
[2,0,2,2] => [4,2,0,0]
[2,4,2,2] => [2,4,4,0]
[2,4,4,2] => [2,8,2,0]
[0,2,0,2] => [4,0,0,0]
  • 因此,我们需要循环旧数组,检测到非0值后,判断后续值是否非0,如果非0,再判断值是否相等,相等则合并将合并值push进新数组,不相等则直接push进新数组,最后余下空位补0,返回新数组,具体代码如下:
function  _2048(arr){
let newArr = [];

for(var i=0; i<arr.length; i++){
if(arr[i] !==0){
//使用break跳出循环,不为0时,j=i+1,为0时,j为不为0元素的下标
for(var j=i+1; j<arr.length; j++){
if(arr[j]!== 0) break;
}
//如果两块相等,则合并
if(arr[i] === arr[j]){
newArr.push(arr[i]+arr[j]);
i =j;
//如果不等,则推进去
}else {
newArr.push(arr[i]);
}
}
}

for(var i=0; i<arr.length; i++){
if(!newArr[i]) newArr.push(0);
}

// console.log(newArr);
return newArr;
}
  • 再将处理完的数据与显示对应起来:
function run(arr) {
let newValue = _2048([
Number(imgs[arr[0]].getAttribute('value')),
Number(imgs[arr[1]].getAttribute('value')),
Number(imgs[arr[2]].getAttribute('value')),
Number(imgs[arr[3]].getAttribute('value'))
])

for(var i=0; i<arr.length; i++){
imgs[arr[i]].setAttribute('value',newValue[i]);
imgs[arr[i]].src = `img/cube_${newValue[i]}.png`;
}

// console.log(newValue);
}
  • 最后,每次按下时还需要生成新的数字块,生成新块首先得判断哪些地方是空的,可以生成,其次,当格子满了后,也无法生成新块:
function create() {
var num = 0;
var random = Math.floor(Math.random()*16);
if(imgs[random].getAttribute('value') == 0){
imgs[random].setAttribute('value',2);
imgs[random].src = `img/cube_2.png`;
}else {
for(var i=0; i<imgs.length; i++){
if(imgs[i].getAttribute('value') != 0){
num++;
}
}
if(num!=imgs.length){
create();
}

}
}

总结

  • 由于是几个月之前写的,整理下来才发现忘了写计分功能,有需要的同学可以自己完善一下,2048的计分为将合并产生的新值记入分数,所以直接在前面处理方块合并的函数中加入计分即可;
  • 其次,当按下某个方向时,如果方块都已经是无法移动了,则不能生成新块,本代码中没有加入此判断,具体实现我觉得应该是判断新旧数组是否产生变化,如果没变化,则不能生成新块;

源码地址:原生JS实现2048小游戏-github

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: