在vue中用canvas画一个简单的贪吃蛇游戏

17 篇文章 0 订阅

canvas和样式: 

 <canvas id="canvas" width="400" height="400"></canvas>

#canvas {

  border: 1px solid #dee2ed;

}

 需要的变量:

<script>
export default {
  data() {
    return {
      ctx: null,
      interval: null,
      snakeData: [],
      count: 0,//步数
      pointList: [{ x: 36, y: 18 }],//默认点
      direction: "d", // 默认右,w:上,s:下,a:左,d:右
      controll: null,//监听
      controll2: null,//监听
      speedCount: 0, // 渲染倍数
      speed: 8 // 渲染倍数分子
    };
  },
  mounted() {
    // 贪吃蛇,canvas
    const canvas = document.getElementById("canvas");
    this.ctx = canvas.getContext("2d"); // 获取绘制上下文
    const list = [];
    for (let i = 0; i < 2; i++) {
      list.push({
        x: 0 + i * 6,
        y: 0,
        type: "right"
      });
    }
    this.snakeData = list;
    console.log("snakeData", this.snakeData);
    this.setView(list);
    this.controll = new AbortController();
    this.controll2 = new AbortController();
    window.addEventListener(
      "keydown",
      val => {
        if (
          val.key === "w" ||
          val.key === "a" ||
          val.key === "s" ||
          val.key === "d"
        ) {
          // 方向不能相反
          switch (val.key) {
            case "w":
              if (this.direction !== "s") {
                this.direction = "w";
                this.speed = 4;
              }
              break;
            case "a":
              if (this.direction !== "d") {
                this.direction = "a";
                this.speed = 4;
              }
              break;
            case "s":
              if (this.direction !== "w") {
                this.direction = "s";
                this.speed = 4;
              }
              break;
            case "d":
              if (this.direction !== "a") {
                this.direction = "d";
                this.speed = 4;
              }
              break;
            default:
              console.log("方向不合法或无效按键");
              break;
          }
        }
      },
      { signal: this.controll.signal }
    );
    window.addEventListener(
      "keyup",
      val => {
        if (
          val.key === "w" ||
          val.key === "a" ||
          val.key === "s" ||
          val.key === "d"
        ) {
          this.speed = 8;
        }
      },
      { signal: this.controll2.signal }
    );
    this.count = 0;
    this.intervalFun();
  },
  beforeDestroy() {
    this.count = 0;
    this.interval && cancelAnimationFrame(this.interval);
    this.controll.abort();
    this.controll2.abort();
  },
  methods: {
    intervalFun() {
      this.count++;
      this.speedCount++;
      // 默认向右移动
      if (this.count > 5000) {
        // clearInterval(this.interval);
        cancelAnimationFrame(this.interval);
      } else {
        if (this.speedCount % this.speed === 0) {
          // 速度缩减10倍,执行10次才渲染1次
          const w = canvas.clientWidth;
          const h = canvas.clientHeight;
          this.ctx.clearRect(0, 0, w, h);
          this.goForword(this.snakeData);
        }
      }

      this.interval = requestAnimationFrame(this.intervalFun);
    },
    goForword(list) {
      // console.log("list1", list);
      const option = { ...list[list.length - 1] };
      if (this.direction === "d") {
        option.x = Number(option.x) + 6;
      } else if (this.direction === "a") {
        option.x = Number(option.x) - 6;
      } else if (this.direction === "w") {
        option.y = Number(option.y) - 6;
      } else if (this.direction === "s") {
        option.y = Number(option.y) + 6;
      }

      list.push(option);
      let flag = false;
      // console.log("option", option);
      this.pointList = this.pointList.filter(item => {
        if (option.x === item.x && option.y === item.y) {
          flag = true;
        }
        return item.x !== option.x || item.y !== option.y;
      });
      if (!flag) {
        list.shift();
      } else {
        // 重新生成点
        const x = Math.floor(Math.random() * Math.round(400 / 6)) * 6;
        const y = Math.floor(Math.random() * Math.round(400 / 6)) * 6;
        this.pointList.push({
          x,
          y
        });
      }
      this.snakeData = list;
      // console.log("snakeData", this.snakeData);
      this.setView(this.snakeData); // 画蛇
      this.setView(this.pointList); // 画点
    },
    setView(list) {
      // this.ctx.clearRact(0, 0, 400, 400);
      this.ctx.beginPath();
      for (let i = 0; i < list.length; i++) {
        this.ctx.rect(list[i].x, list[i].y, 6, 6); // 绘制矩形
      }
      this.ctx.fill(); // 描边一个矩形轮廓
    }
  }
};
</script>

<template>
  <div class="content">
    <h3>贪吃蛇</h3>
    <canvas id="canvas" width="400" height="400"></canvas>
  </div>
</template>

<style lang="less" scoped>
#canvas {
  border: 1px solid #dee2ed;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值