2048小游戏 - vue实现

avatarplhDigital nomad

前言

数据结构与算法对这种小游戏的实现非常重要,mmp我写了一个月,断断续续晚上写才想好思路呢。,

demo 源码

265318332093295980

core核心代码

class Stack{},用一个数据结构,叫做栈。但他并不是栈。这个类内部存储一个长度为16个长度的数组。使用的时候为方块x,y,num,color,不占用的时候为null,为什么这样做呢,因为打算用它去双向绑定view视图区渲染。为了动画效果,我们只能更新移动的数据,而它指向stack内部的item数组。所以数组内部只能更新个别数组,不能重新写一个数组,出于种种考虑,stack拥有add,remove,isExist内部方法,而后在vue的mouted钩子函数内部调用stack.add()添加方块。

vue+动画+移动算法的结合

// 移动
turn(direct) {
  this.rocks.forEach(e => e&&(e.canCalc = true));
  Promise.all(
    this.handleDirect(direct).handleArr(this.rocks)
      // 将他们移到最右
      .map(async e => {
        let next = this.isExist(this.handleDirect(direct).next(e));
        return this.calcAxis({ e ,direct});
      })
  ).then(res => {
    if (res.indexOf(true) > -1) {
      this.add();
      this.add();
    } else {
      console.log("没有移动,不用添加");
    }
    setTimeout(() => {
      if(this.isGameOver()){
        alert('游戏结束!')
        // this.init();
      }
    }, 0);
  });
},
// 处理移动距离的函数
calcAxis({ e,direct }) {
  return new Promise(async (resolve, reject) => {
    let next = this.isExist(this.handleDirect(direct).next(e));
    if (next && next.num !== e.num) {
      resolve(false);
    } else if (next && next.canCalc && next.num === e.num) {
      // 3个条件,不为null,
      this.handleDirect(direct).handleMove(e)
      e.num*=2;
      this.scort+=e.num;
      e.canCalc = false;
      e.color=this.color[e.num]
      const dom = document.querySelector(`#r${e.id}`)
      dom.animate([
        { transform: 'scale(1)' }, 
        { transform: 'scale(1)' }, 
        { transform: 'scale(1)' }, 
        { transform: 'scale(1)' }, 
        { transform: 'scale(0.95)' }, 
        { transform: 'scale(1.1)' }, 
        { transform: 'scale(1.03)' }, 
        { transform: 'scale(1)' } 
      ], { 
        duration: 200,
      });
      // dom.style
      this.rocks.splice(this.getIndex(next.id), 1, null);
      resolve(true);
    } else if (next === undefined) {
      if (this.handleDirect(direct).handleCondition(e)) {
        this.handleDirect(direct).handleMove(e)
        this.calcAxis({ e,direct });
      }
      resolve(true);
    }
  });
}