基于Vue2实现贪吃蛇2【中秋主题暨月更挑战第21天】

66 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情 >>

前言

上一篇我们实现了贪吃蛇的核心功能,但是还是有很多小瑕疵,比如一进页面就开始了,而且不能暂停,速度不能调整等等,还有就是蛇移动的时候没有动效,非常不好看,这篇就是基于上一篇的代码,来实现一些更好看的移动效果

增加开始暂停结束按钮

首先,我们先增加一个按钮,通过定位的方式定在页面下方,水平居中,通过判断是开始还是暂停还是结束,显示不同的按钮

// template
<div class="start" v-if="!fail" :class="[pause?'pause':'']"></div>
<div class="end" v-else></div>
//data
...
pause: false,
fail: false
...
// less
.start{
    width: 110px;
    height: 37px;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background-image: url("~@/assets/start.png");
    background-size: contain;
    background-position: center;
    cursor: pointer;
  }
  .start.pause{
    background-image: url("~@/assets/pause.png");
  }
  .end{
    width: 110px;
    height: 37px;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background-image: url("~@/assets/restart.png");
    background-size: contain;
    background-position: center;
    cursor: pointer;
  }

这个时候,我们就把按钮放在页面下方了

image.png 接下来就是给按钮添加事件,能够开始和暂停,然后需要在move函数内判断失败的地方,处理重新开始逻辑,并给重新开始的按钮添加事件

start () {
  if (!this.pause) {
    clearInterval(this.t)
    this.t = null
  } else {
    this.t = setInterval(() => {
      this.move()
    }, 2000)
  }
},
// move 函数内判断失败
 // 判断不能撞到自己
  for (const i in this.xyMap) {
    if (this.xyMap[newHead.x + '_' + newHead.y] === this.xyMap[i]) {
      this.fail = true
      this.showEnd = true
      clearInterval(this.t)
    }
  }
  // 判断不能撞墙
  if (newHead.x + 1 > 40 || newHead.y + 1 > 50 || newHead.x < 0 || newHead.y < 0) {
    this.fail = true
    this.showEnd = true
    clearInterval(this.t)
  }

image.png

这里页面上失败的背景图出现了多个,这是因为我们设置css 背景图的时候没有指定background-repeat: no-repeat 这里,当background-size: contain;的时候,背景图会缩放到能完全展示的程度,进行展示,这时,假如无法铺满容器,就会出现重复,设置no-repeat可以指定背景图片不重复

速度调节

速度一成不变的运动给人带来的挑战和刺激都不太够,所以,我们需要设计一种机制,让吃的越多,蛇就跑的越快,那么我们该如何实现呢?蛇的运动是通过setinterval重复调用move函数实现的,也就是说,我们动态改变interval的刷新时间,就可以改变蛇的运动速度,如何实现呢?这里,每当蛇吃到食物的时候就会更新食物坐标,我们在设置食物的同时进行判断不就可以了吗?这样,我们就需要改写一下food函数

food () {
      const inx = this.xy.length % 3
      if (inx === 0) {
        clearInterval(this.t)
        this.t = null
        this.pause = false
        this.speed -= 50
        this.start()
      }
      // 不能放在蛇身上
      let x, y
      .....

这里,我们判断蛇身长度对3取余,如果为0,说明又吃到了三个食物,然后我们就调整速度,让速度比之前快50ms,这样就实现了速度的变化,然后打开页面,发现哎?为什么直接就开始动了?我还没点开始啊?这是因为,我们在created的时候生成了食物坐标, food函数又被我们改写了,于是就会走进inx === 0的判断内,触发开始,这里,我们需要添加一个判断,就是蛇身坐标长度大于3

 if (this.xy.length > 3) {
        const inx = this.xy.length % 3
        if (inx === 0) {
          clearInterval(this.t)
          this.t = null
          this.pause = false
          this.speed -= 50
          this.start()
        }
      }

这样,就不会出现生成食物的同时触发开始了。 完整的代码以代码片段的形式呈现如下,欢迎试玩儿