直接Vue上代码文章来源:https://uudwc.com/A/20jNw
<template>
<div>
<div>贪吃蛇</div>
<canvas id="canvas" width="400" height="400"></canvas>
</div>
</template>
<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>
<style lang="scss" scoped>
#canvas {
border: 1px solid #dee2ed;
}
</style>
直接拿着用即可文章来源地址https://uudwc.com/A/20jNw