一、前言
- 你就玩吧,一玩一个不吱声!
- 素材在文章里,不想要带水印的话可以评论留言找我拿原图。
- 比较仓促,不足之处,欢迎交流
二、素材
三、代码注释详解
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>