<template>
  <div class="changdi" @keyup="keyup">
    <div class="menu">
      <div class="caozuo">
        <el-button @click="start">开始</el-button>
        <el-button @click="pause">暂停</el-button>
      </div>
      <div class="fen">得分:{{fen}}</div>
      <div class="sudu">
        <el-button @click="jiasu">加速</el-button>
        <el-button @click="jiansu">减速</el-button>
      </div>
    </div>
    <div class="ditu">
      <div ref="heng" class="heng" v-for="i in hg " :key="i">
        <div ref="shu" class="shu" v-for="t in sg " :key="t">
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      hg: 40, //横格子数
      sg: 40, //竖格子数
      speed: 200, //前进速度 单位 ms
      fen: 0, //前进速度 单位 ms
      sheshen: [], //蛇身位置数组
      zhanwei: {}, //蛇身递进占位
      guozi: {}, //果子位置
      lastcaozuo: "xiangyou",
      caozuo: null, //操作定时器
      shewei: {}, //蛇尾位置
    };
  },
  methods: {
    //初始化蛇的长度位置
    init() {
      this.clear();
      this.sheshen = [,];
      this.sheshen[0] = { h: 5, s: 6 };
      this.sheshen[1] = { h: 5, s: 5 };
      this.setguozi();
      this.fen = 0;
      this.lastcaozuo = "xiangyou";
      this.shewei = {};
      this.pause();
      document.querySelector(".tou").style.transform = "rotate(0)";
    },

    //游戏开始
    async start() {
      this.go();
      clearInterval(this.caozuo);
      this.caozuo = null;
      this.caozuo = setInterval(() => {
        this.go();
      }, this.speed);
    },

    //出发
    go() {
      switch (this.lastcaozuo) {
        case "xiangyou":
          this.you();
          break;
        case "xiangshang":
          this.shang();
          break;
        case "xiangxia":
          this.xia();
          break;
        case "xiangzuo":
          this.zuo();
          break;
      }
    },

    //暂停
    pause() {
      clearTimeout(this.caozuo);
    },

    //加速
    jiasu() {
      this.speed /= 2;
    },

    //减速
    jiansu() {
      this.speed *= 2;
    },

    //记录最后一个位置
    setshewei() {
      this.shewei = this.sheshen[this.sheshen.length - 1];
    },

    //生成果子
    setguozi() {
      let h = parseInt(Math.random() * this.hg);
      let s = parseInt(Math.random() * this.sg);
      this.guozi = { h: h, s: s };
      this.change();
    },

    //刷新视图
    change() {
      try {
        this.clear();
        this.chiguozi();

        if (
          //死亡条件
          this.sheshen[0].h >= this.hg ||
          this.sheshen[0].h < 0 ||
          this.sheshen[0].s < 0 ||
          this.sheshen[0].s >= this.sg
        ) {
          alert("×_×你死了");
          this.init();
        }

        //刷新果子视图
        this.$refs.heng[this.guozi.h].children[this.guozi.s].className =
          "shu guozi";
        this.sheshen.forEach((i, t) => {
          //刷新蛇身视图
          this.$refs.heng[i.h].children[i.s].className = "shu sheshen";

          if (t > 0) {
            if (i.h === this.sheshen[0].h && i.s === this.sheshen[0].s) {
              alert("");
              this.init();
            }
          } else {
            this.$refs.heng[i.h].children[i.s].className = "shu sheshen tou";
          }
        });

        this.zhuantou();
      } catch {}
    },

    //头部方向转动
    zhuantou() {
      if (this.lastcaozuo === "xiangshang") {
        document.querySelector(".tou").style.transform = "rotate(-90deg)";
      } else if (this.lastcaozuo === "xiangxia") {
        document.querySelector(".tou").style.transform = "rotate(90deg)";
      } else if (this.lastcaozuo === "xiangzuo") {
        document.querySelector(".tou").style.transform = "rotate(180deg)";
      } else if (this.lastcaozuo === "xiangzuo") {
        document.querySelector(".tou").style.transform = "rotate(0)";
      }
    },

    you() {
      this.sheshen.forEach((i, t) => {
        if (t === 0) {
          this.zhanwei = i;
          this.sheshen[t] = { h: i.h, s: i.s + 1 };
        } else {
          this.sheshen[t] = this.zhanwei;
          this.zhanwei = i;
        }
      });
      this.change(); //刷新视图
    },
    xia() {
      this.sheshen.forEach((i, t) => {
        if (t === 0) {
          this.zhanwei = i;
          this.sheshen[t] = { h: i.h + 1, s: i.s };
        } else {
          this.sheshen[t] = this.zhanwei;
          this.zhanwei = i;
        }
      });
      this.change(); //刷新视图
    },
    shang() {
      this.sheshen.forEach((i, t) => {
        if (t === 0) {
          this.zhanwei = i;
          this.sheshen[t] = { h: i.h - 1, s: i.s };
        } else {
          this.sheshen[t] = this.zhanwei;
          this.zhanwei = i;
        }
      });
      this.change(); //刷新视图
    },
    zuo() {
      this.sheshen.forEach((i, t) => {
        if (t === 0) {
          this.zhanwei = i;
          this.sheshen[t] = { h: i.h, s: i.s - 1 };
        } else {
          this.sheshen[t] = this.zhanwei;
          this.zhanwei = i;
        }
      });
      this.change(); //刷新视图
    },

    //吃果子函数
    chiguozi() {
      //当蛇首和果子位置相同时
      if (
        this.sheshen[0].h === this.guozi.h &&
        this.sheshen[0].s === this.guozi.s
      ) {
        //生成新果子
        this.fen++;
        this.setguozi();
        this.sheshen.push(this.shewei);
      }
    },

    //清空视图
    clear() {
      for (let i = 0; i < this.hg; i++) {
        for (let t = 0; t < this.sg; t++) {
          this.$refs.heng[i].children[t].className = "shu";
        }
      }
    },
  },
  mounted() {
    window.addEventListener("keyup", (i) => {
      //不能原地掉头和平地加速  如需平地加速请注释第二个条件
      switch (i.keyCode) {
        case 37:
          if (
            this.lastcaozuo !== "xiangyou" &&
            this.lastcaozuo !== "xiangzuo"
          ) {
            this.lastcaozuo = "xiangzuo";
            this.start();
          }
          break;
        case 38:
          if (
            this.lastcaozuo !== "xiangxia" &&
            this.lastcaozuo !== "xiangshang"
          ) {
            this.lastcaozuo = "xiangshang";
            this.start();
          }
          break;
        case 39:
          if (
            this.lastcaozuo !== "xiangzuo" &&
            this.lastcaozuo !== "xiangyou"
          ) {
            this.lastcaozuo = "xiangyou";
            this.start();
          }
          break;
        case 40:
          if (
            this.lastcaozuo !== "xiangshang" &&
            this.lastcaozuo !== "xiangxia"
          ) {
            this.lastcaozuo = "xiangxia";
            this.start();
          }
          break;
        case 32:
          this.pause();
          break;
      }
    });
    this.init();
  },
};
</script>
<style lang="css">
   .changdi{
  padding: 20px 100px;
  display: inline-block;
  height: 850px;
  background-color: #000;
  position: relative;
  }
  .menu{
   display: flex;
   align-items: center;
   justify-content: space-around;
   height: 60px;
   color: #fff;
  }
  .ditu{
   background-color: #fff;
  }
 

  .heng{
   margin: 0;
   padding: 0;
   height: 20px;
  }
  .shu{
   display: inline-block;
   width: 20px;
   height: 20px;
   background-color: #fff;
   box-sizing: border-box;
   position: relative;
  }
  .guozi::before{
     content: '';
     display: inline-block;
     width: 16px;
     height: 16px;
     background-color: #f00;
     position: absolute;
    border-radius: 50%;
    top: 1px;
    left: 1px;
   }   
  .sheshen{
   display: inline-block;
   width: 20px;
   height: 20px;
   background-color: #fff;
   box-sizing: border-box;
   position: relative;
   background-color: #000;
  }
  .tou{
    background-color: #000;
    position: relative;
    border-radius: 0 9px 3px 0;
    overflow: hidden;
  }
  .tou::after{
    content: '';
    display: inline-block;
    width: 12px;
    height: 3px;
    background-color: rgb(126, 4, 4);
    border-radius: 50% 0 0 50%;
    position: absolute;
   bottom: 3px;
   right: 0;
  }
  .tou::before{
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    background-color: rgb(32, 117, 11);
    position: absolute;
   border-radius: 50%;
   top: 3px;
   right: 3px;
  }
</style>
