VUE小游戏——打地鼠

一、前言

  • 你就玩吧,一玩一个不吱声!
  • 素材在文章里,不想要带水印的话可以评论留言找我拿原图。
  • 比较仓促,不足之处,欢迎交流

二、素材

三、代码注释详解

xml 复制代码
<template>
  <div class="box">
    <div class="gameBox">
      <div class="fraction">当前积分:{{ data.fraction }}</div>
      <img src="../../public/bg.jpg" alt="" class="bg">
      <div class="startBtn" @click="startGame">开始游戏</div>
      <img src="../../public/hamster.png" alt="" :class="[data.classObj, 'hole1']" @click="hamsterClick">
      <div class="operatePrompt" v-if="data.operatePromptFlag">
        <div>恭喜! 你通关了!</div>
        <div class="operateBtn">
          <button class="exit" @click="exit">退出</button>
          <button class="continue" @click="continueGame">重新开始</button>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive,  computed } from 'vue';
const data = reactive({
  fraction: 0,
  hamsterNum: 0,
  classObj: { 'hamster': true },
  setIntervalFlag: null,
  operatePromptFlag: false,
})
// 强制退出!!!
const exit = () => {
  let confirmFlag = confirm("是否真的要退出,请确认?");
  if (confirmFlag || !confirmFlag) {
    window.location.href = "https://juejin.cn/post/7306043013818023951"
  }
}
// 再来一次,重新开始
const continueGame = () => {
  data.hamsterNum = 0
  data.classObj = { 'hamster': true }
  data.operatePromptFlag = false
}
//封装随机数,包含min, max值
const getRandom = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 随机出洞
// 动态添加类名,随机地鼠露头
const stochastic = () => {
  // 定时器间隔决定地鼠随机的速度
  data.setIntervalFlag = setInterval(() => {
    // 八个洞口随机1-7的数字(包含1、7)
    let num = getRandom(1, 7)
    // 赋初始值,防止类名混乱
    data.classObj = { 'hamster': true }
    //随机添加某个地鼠类名
    data.classObj['hole' + num] = true
  }, 300)
}
// 开始游戏
const startGame = () => {
  if (data.operatePromptFlag) return
  // 如果定时器存在清除之后再随机,防止重复触发,这里也可以用防抖节流替代
  if (data.setIntervalFlag) {
    clearInterval(data.setIntervalFlag)
    data.setIntervalFlag = null
    // console.log(data.setIntervalFlag, '???');
    stochastic()
  } else {
    stochastic()
  }
  // console.log(data.classObj);
}
// 点击地鼠
const hamsterClick = () => {
  // 如果等于900积分,则继续++,随后终止清除定时器
  if (data.fraction == 900) {
    data.hamsterNum++
    data.operatePromptFlag = true
    clearInterval(data.setIntervalFlag)
    data.setIntervalFlag = null
    return
  }
  // 不等于900则自身++
  data.hamsterNum++
}
// 计算积分
data.fraction = computed(() => {
  return data.hamsterNum * 100
})
// const { } = toRefs(data)
</script>
<style scoped lang="scss">
.hole1 {
  left: 100px;
  top: 210px;
}

.hole2 {
  left: 243px;
  top: 210px;
}

.hole3 {
  left: 30px;
  top: 285px;
}

.hole4 {
  left: 175px;
  top: 285px;
}

.hole5 {
  left: 322px;
  top: 285px;
}

.hole6 {
  left: 100px;
  top: 370px;
}

.hole7 {
  left: 243px;
  top: 370px;
}

.hole8 {
  left: 100px;
  top: 210px;
}

.gameBox {
  width: 400px;
  margin: 0 auto;
  position: relative;

  .fraction {
    color: #8bff00;
    font-size: 30px;
  }

  .bg {
    width: 400px;
    height: 400px;
    margin: 20px 0;
  }

  .startBtn {
    background: url('../../public/bg.jpg');
    width: 200px;
    height: 50px;
    border-radius: 20px;
    text-align: center;
    line-height: 50px;
    color: #04827d;
    letter-spacing: 10px;
    margin: 0 auto;
  }

  .hamster {
    position: absolute;
    width: 50px;
    height: 50px;
    display: inline-block;
    cursor: pointer;
  }

  .operatePrompt {
    width: 300px;
    height: 300px;
    background-color: rgba(0, 0, 0, 0.29);
    text-align: center;
    font-size: 40px;
    color: aqua;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    // z-index: 999;
    .operateBtn {
      margin-top: 40px;

      .continue {
        font-size: 18px;
        width: 150px;
        height: 40px;
        border-radius: 20px;
        border: 0;
        color: blue;
      }

      .exit {
        font-size: 18px;
        width: 75px;
        height: 40px;
        border-radius: 20px;
        margin-right: 20px;
        border: 0;
        color: crimson;
      }

      .continue:hover,
      .exit:hover {
        cursor: pointer
      }
    }
  }
}
</style>
相关推荐
袁煦丞37 分钟前
【局域网秒传神器】LocalSend:cpolar内网穿透实验室第418个成功挑战
前端·程序员·远程工作
江城开朗的豌豆38 分钟前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js
Goboy44 分钟前
打造梦幻又实用的 Mermaid 马卡龙渐变风主题 —— 技术博主必备视觉指南
程序员·产品·设计
爱钓鱼的老毕登1 小时前
2025编程革命:氛围编码崛起,开发者如何成为AI策展人?
人工智能·程序员·cursor
好奇心笔记1 小时前
ai写代码随机拉大的,所以我准备给AI出一个设计规范
前端·javascript
江城开朗的豌豆1 小时前
Vue状态管理进阶:数据到底是怎么"跑"的?
前端·javascript·vue.js
用户21411832636021 小时前
dify案例分享-Dify v1.6.0 重磅升级:双向 MCP 协议引爆 AI 生态互联革命
前端
程序员海军1 小时前
AI领域又新增协议: AG-UI
前端·openai·agent
我想说一句1 小时前
React待办事项开发记:Hook魔法与组件间的悄悄话
前端·javascript·前端框架
真夜1 小时前
CommonJS与ESM
前端·javascript