原生Js实现2048小游戏

介绍:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值