首先定义一个Target的接口来定义坐标点
interface Target{
x: number,
y: number
}
定义一个Snake的接口存在所需要的变量
interface Snake {
arr: Target[],//存放所有的数组
activeArr: Target[],//存放蛇位置的数组
target:Target,//目标点坐标
direction:number,//方向 上下左右
timer:number//蛇移动速度
}
初始化一个reactive
const count = reactive<Snake>({
arr: [],
activeArr:[],
target:{x:random(0,50),y:random(0,50)},
timer:1000,
direction:random(0,4) // 随机一个方向 0 1 2 3 4 5 6 7 上下左右 只写了0-4 后边想写能斜着移动呢
})
生成随机数
const random=(min:number,max:number):number=>{
return Math.floor(Math.random() * max+min)
}
初始化
const init=():void=>{
handleKeyDown()
//生成表格
for (let i = 0; i < 50; i++) {
for (let j = 0; j < 50; j++) {
count.arr.push({
x:j,
y:i
})
}
}
// 初始化时不让它在最边上 默认长度是 4
let x=random(4,45)
let y=random(4,45)
count.activeArr.push({x,y})
switch (count.direction) {
case 0:
count.activeArr.push({x,y:y+1},{x,y:y+2},{x,y:y+3})
break;
case 1:
count.activeArr.push({x,y:y-1},{x,y:y-2},{x,y:y-3})
break;
case 2:
count.activeArr.push({x:x+1,y},{x:x+2,y},{x:x+3,y})
break;
default:
count.activeArr.push({x:x-1,y},{x:x-2,y},{x:x-3,y})
break;
}
//生成目标点
count.target=targetFn()
// 检测键盘方向键
//开启定时器
const timer=setInterval(()=>{
let x=count.activeArr[0].x
let y=count.activeArr[0].y
switch (count.direction) {
case 0:
y--
break;
case 1:
y++
break;
case 2:
x--
break;
default:
x++
break;
}
if(y<0||y>49||x<0||y>49){
alert('Game Over');
clearInterval(timer)
return
}
let endSpot=count.activeArr.pop()
count.activeArr.unshift({x,y})
// 吃到了 重新生成目标点
console.log(count.target,x,y);
if(count.target.x==x&&count.target.y==y){
console.log('进来');
count.target=targetFn()
count.activeArr.push(endSpot as Target)
}
},count.timer)
}
生成目标点 以及监听键盘事件
const targetFn=():Target=>{
let target:Target={x:random(0,50),y:random(0,50)}
return count.activeArr.some(item1 => item1.x === target.x && item1.y === target.y)?targetFn():target
}
const handleKeyDown=()=>{
document.onkeydown=event=>{
switch(event.key) {
case 'ArrowUp':
if(count.direction==0)return
count.direction = 0;
break;
case 'ArrowDown':
if(count.direction==1)return
count.direction = 1;
break;
case 'ArrowLeft':
if(count.direction==2)return
count.direction = 2;
break;
case 'ArrowRight':
if(count.direction==3)return
count.direction = 3;
break;
default:
break;
}
console.log(event.key);
}
}
最后 执行初始化方法
onMounted(init)
其他代码
<template>
<div id="div">
<div v-for="item in count.arr" :class="{active:count.activeArr.some(item1 => item1.x === item.x && item1.y === item.y),target:item.x==count.target.x&&item.y==count.target.y}"></div>
</div>
</template>
<style scoped>
#div {
width: 500px;
height: 500px;
margin: auto;
display: flex;
border: 1px solid #ccc;
flex-wrap: wrap
}
#div>div {
width: 10px;
height: 10px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.active{
background:#ccc;
}
.target{
background:red;
}
</style>
另外提出一个问题,箭头所指这里 是不是要用断言?