vue3 贪吃蛇。

<script setup lang="ts">
import { ref, onMounted,onUpdated } from "vue";
// 分数
let fraction = ref<number>(0);
// 等级
let grade =ref<string>('菜鸡')
//  动物头部
let snakeHeader: HTMLElement;

let audio=ref('audio')


// 动物身体
let headers: NodeListOf<HTMLElement>;
//  动物初始位置
let snkeTop: number;
let snakeLeft: number;

// 时间判定 等级判定
let timerNum = ref(200);
// 获取食物
let foot: HTMLElement;
// 食物初始位置
let footTop: number;

let increase =ref(0)
let dialogVisible=ref(false)
let title =ref('你撞墙了!')
let bo:HTMLAudioElement

let bofang=()=>{
console.log(bo);

  bo.play()
}
 let zanting=()=>{
  bo.pause();
 }
onMounted(() => {
  console.log(audio);
  bo=document.querySelector('.music')!
  // 获取动物 需要挂载完毕才能获取
  // snake = document.querySelector(".snake")!;
  // 获取初始身体部位
  headers = document.querySelectorAll(".headers");

  //  获取动物头部
  snakeHeader = document.querySelector(".header")!;
  //  获取头部初始位置
  snkeTop = snakeHeader.offsetTop;
  snakeLeft = snakeHeader.offsetLeft;
  console.log(snkeTop, snakeLeft);

  // 获取食物
  foot = document.querySelector(".foot")!;

  footwei();

  window.addEventListener("keydown", move);
});

onUpdated(()=>{
  headers = document.querySelectorAll(".headers");

})
// 碰到墙体上下
let collision = (a: number,b:NodeJS.Timeout ): void => {
    if(a<0||a>390){
          dialogVisible.value=true
// 清除定时器
title.value='你撞墙啦!'
          clearInterval(b);
        }
};
// 碰到墙体左右
let collisions = (a: number,b:NodeJS.Timeout ): void => {
    if(a<0||a>370){
          dialogVisible.value=true
          title.value='你撞墙啦!'
// 清除定时器
          clearInterval(b);
        }
};
// 碰撞自身判断
let eatMy=(a:NodeJS.Timeout):void=>{
  headers.forEach((item)=>{
   if( snakeHeader.offsetLeft==item.offsetLeft&&snakeHeader.offsetTop==item.offsetTop){

    dialogVisible.value=true
    title.value='你想吃掉自己呀宝!'
    clearInterval(a)
   }
  })
}

     // 碰墙判断
   
// 吃到食物函数
let eactFoot = function (): void {
  // 蛇头位置和食物位置相同
  if (snkeTop == foot.offsetTop && snakeLeft === foot.offsetLeft) {
  
    increase.value++
    // 刷新食物位置
    footwei();
    // 分数上升
    fraction.value = fraction.value + 1;

    // 等级上升
    if (fraction.value >= 3) {
      timerNum.value = 100;
      // 等级
      grade.value='厉害孟'
    }else if(fraction.value >= 6){
      timerNum.value = 50;
      grade.value='开挂孟'
    }
  }
};

let footwei = (): void => {
  // 获取食物初始位置
  let a = Math.round(Math.random() * 37) * 10;
  let b = Math.round(Math.random() * 37) * 10;
  console.log(a, b);

  foot.style.top = a + "px";
  foot.style.left = b + "px";
};
// console.log(e);

// let timer:{
//   timerTop
// }
// 向上定时器
let timerTop: NodeJS.Timeout;
// 向左定时器
let timerTLeft: NodeJS.Timeout;
// 向右定时器
let timerTRight: NodeJS.Timeout;
// 向下定时器
let timerBottm: NodeJS.Timeout;

// 身体控制转向
let shenti=()=>{
  for(let i=headers.length-1;i>=0;i--){

if (i == 0) {
          headers[i].style.left = snakeLeft + "px";
          headers[i].style.top = snkeTop + "px";

        }else{
          headers[i].style.left=headers[i-1].offsetLeft+'px'
          headers[i].style.top=headers[i-1].offsetTop+'px'
        }

}
}


// 转向锁

let up: boolean = true;
let dowm: boolean = true;
let left: boolean = true;
let right: boolean = true;
// 清除定时器
// let clearTimer = () => {
//   // 清除多余定时器
//   clearInterval(timerTop);
//   clearInterval(timerTLeft);
//   clearInterval(timerTRight);
//   clearInterval(timerBottm);
// };

// 重新开始
let chongxin=()=>{
  dialogVisible.value = false
  // 分数清零
  fraction.value=0
  // 难度清零
  timerNum.value=200
  // 蛇头位置随机刷新
  let a = Math.round(Math.random() * 37) * 10;
  let b = Math.round(Math.random() * 37) * 10;
  snakeHeader.style.top = a + "px";
  snakeHeader.style.left = b+ "px";
  snkeTop = a;
  snakeLeft = b;

  // 身体初始化
  increase.value=0
  
}


let move = (e: KeyboardEvent) => {
  // 按上
  if (e.key == "ArrowUp") {
    if (up) {
      dowm = false;
      left = true;
      right = true;

      clearInterval(timerTop);
      clearInterval(timerTLeft);
      clearInterval(timerTRight);
      clearInterval(timerBottm);

      // 开启x向上定时器
      timerTop = setInterval(() => {
        // 逐步移动
        shenti()

        snkeTop -= 10;
        snakeHeader.style.top = snkeTop + "px";
    
        eatMy(timerTop)
   
        // 吃到食物
        eactFoot();
        // 碰撞测试
        collision(snkeTop,timerTop)
      }, timerNum.value);
    }

    // console.log(snake);

    // 清除多余定时器
  }
  // 按右
  else if (e.key == "ArrowRight") {
    if (right) {
      up = true;
      dowm = true;

      left = false;

      // 清除多余定时器
      clearInterval(timerTop);
      clearInterval(timerTLeft);
      clearInterval(timerTRight);
      clearInterval(timerBottm);
      timerTLeft = setInterval(() => {

       
     
       
        shenti()
          
        
        snakeLeft += 10;
        snakeHeader.style.left = snakeLeft + "px";

        eatMy(timerTLeft)
        eactFoot();
        collisions(snakeLeft,timerTLeft)
      }, timerNum.value);
    }
  }
  // 向下
  else if (e.key == "ArrowDown") {
    if (dowm) {
      up = false;
      left = true;
      right = true;
      clearInterval(timerTop);
      clearInterval(timerTLeft);
      clearInterval(timerTRight);
      clearInterval(timerBottm);
      // 开启x向下定时器
      timerBottm = setInterval(() => {
        shenti()
  
        snkeTop += 10;
        snakeHeader.style.top = snkeTop + "px";
        eactFoot();
        eatMy(timerBottm)
        collision(snkeTop,timerBottm)
      }, timerNum.value);
    }
  }
  // 向左
  else if (e.key === "ArrowLeft") {
    if (left) {
      up = true;
      dowm = true;

      right = false;
      // 清除多余定时器
      clearInterval(timerTop);
      clearInterval(timerTLeft);
      clearInterval(timerTRight);
      clearInterval(timerBottm);
      timerTRight = setInterval(() => {
        shenti()

        snakeLeft -= 10;
        snakeHeader.style.left = snakeLeft + "px";
        eactFoot();
        eatMy(timerTRight)
        collisions(snakeLeft,timerTRight)
      }, timerNum.value);
    }
  }
};
</script>

<template>
  <div class="box">
   


    <div class="banner">
      <!-- 食物 -->
      <div class="foot"></div>
      <!-- <input  type="password" name="" id=""> -->

      <div class="header"></div>
      <div class="headers" v-for="(i,n) in increase" :key="n"></div>
    </div>

    <div class="jifen">
      <div class="fenshu">分数:{{ fraction }}</div>

      <div class="dengji">等级:{{grade}}</div>
    </div>
    <div class="anniu">
      <el-button type="primary" @click="bofang" round>播放</el-button>
      <el-button type="danger"  @click="zanting" round>暂停</el-button>
    </div>
  <div class="auto">  <audio ref="audio" style="width:0"
        src="https://sucai.suoluomei.cn/sucai_zs/video/20191106172238-xiaoguojiang.mp3"
        controls class="music"></audio>
 <div>   </div></div>
    <el-dialog
  :show-close="false"
  :close-on-click-modal="false"
  :center="true"
    v-model="dialogVisible"
    title="嘿嘿!"
    width="30%"
    
  >
    <span>{{title}}</span>

    <template #footer>
      
     
        <el-button type="primary" @click="chongxin"
          >重新开始</el-button
        >
     
    </template>
   
  </el-dialog>
 

  </div>
  
</template>

<style scoped lang="scss">
.box {
  width: 400px;
  height: 550px;

  border-radius: 5px;
  background-color: #009394;
  box-shadow: 0px 0px 4px 4px #009394 ;
  padding: 10px;
  .banner {
    position: relative;
// background: url(../images/4cc21eb4771eed1b5faaea7fbe1d5b3.jpg);
    width: 100%;
    height: 400px;
    border-radius: 5px;
    background-size: 100% 130%;
    background: #fff;

    .foot {
      position: absolute;
      left: 170px;
      top: 50px;
      border-radius: 50%;
      width: 10px;
      height: 10px;
      background: red;

      // border-radius: 50%;
    }

    .header {
      position: absolute;
      left: 40px;
      top: 300px;
border-radius: 30%;
box-shadow: 0px 0px 10px 2px rgb(128, 125, 125);
      width: 10px;
      height: 10px;
      background: #a163f7
    }
    .headers {
      position: absolute;
      left: 740px;
      top: 510px;
      width: 10px;
      border-radius: 50%;
      
      height: 10px;
      background: #6f88fc;
    }
  }
  .jifen {
    display: flex;
    margin-top: 20px;
    padding: 0 50px;
    font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;

    justify-content: space-between;
  }

  .anniu {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;
    padding: 0 100px;
    font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
  }
}
:deep(.el-dialog__body) {
  text-align: center !important ;

  
}
.auto{position: absolute;
  top: 267px;
    left: 47px;}
</style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值