为了让404页面不再无聊 ( ̄▽ ̄)ノ,我们设计了这个跳一跳小游戏 ヽ(^o^)丿。来挑战一下,看看你能跳多高吧!╰(°▽°)╯"
大致如下
<template>
<div class="not-found">
<div class="content">
<div class="message">
<h1>404 - 页面未找到</h1>
<p>您输入的路径无效,请检查后重试。</p>
</div>
<div class="game-container">
<div class="dino" :style="{ bottom: dinoBottom + 'px', left: dinoLeft + 'px' }">
<span>{{ dinoEmoji }}</span>
</div>
<div class="obstacle" :style="{ left: obstacleLeft + 'px', color: obstacleColor }">
<span>{{ obstacleEmoji }}</span>
</div>
</div>
<div class="health-bar">
<div class="health" :style="{ width: health + '%' }"></div>
</div>
<p class="instructions">按空格键跳跃,可二段跳!</p>
<a href="http://localhost:8080/" class="home-link">返回主页</a>
</div>
</div>
</template>
<script>
export default {
name: 'NotFound',
data() {
return {
dinoBottom: 20,
dinoLeft: 50,
obstacleLeft: 800,
isJumping: false,
jumpCount: 0,
jumpStrength: 0,
gravity: 0.9,
obstacleSpeed: 5,
health: 100,
obstacleEmoji: '(╯°□°)╯︵ ┻━┻',
obstacleColor: '#FF4500',
dinoEmoji: '(ง •̀_•́)ง',
normalDinoEmoji: '(ง •̀_•́)ง',
hurtDinoEmoji: '(x_x)'
}
},
mounted() {
window.addEventListener('keydown', this.handleKeyDown)
this.gameInterval = setInterval(this.updateGame, 20)
},
beforeUnmount() {
window.removeEventListener('keydown', this.handleKeyDown)
clearInterval(this.gameInterval)
},
methods: {
handleKeyDown(event) {
if (event.code === 'Space' && this.jumpCount < 2) {
this.isJumping = true
this.jumpStrength = 15
this.jumpCount++
}
},
updateGame() {
if (this.isJumping) {
this.dinoBottom += this.jumpStrength
this.jumpStrength -= this.gravity
if (this.dinoBottom <= 20) {
this.dinoBottom = 20
this.isJumping = false
this.jumpCount = 0
}
}
this.obstacleLeft -= this.obstacleSpeed
if (this.obstacleLeft < -50) {
this.obstacleLeft = 800
this.obstacleEmoji = this.getRandomEmoji()
this.obstacleColor = this.getRandomColor()
}
this.checkCollision()
},
checkCollision() {
if (this.dinoLeft < this.obstacleLeft + 50 &&
this.dinoLeft + 50 > this.obstacleLeft &&
this.dinoBottom < 70) {
this.health -= 34
if (this.health <= 0) {
alert('游戏结束')
this.health = 100
}
this.obstacleLeft = 800
this.showHurtExpression()
}
},
showHurtExpression() {
this.dinoEmoji = this.hurtDinoEmoji
setTimeout(() => {
this.dinoEmoji = this.normalDinoEmoji
}, 500)
},
getRandomEmoji() {
const emojis = ['(╯°□°)╯︵ ┻━┻', '(ง •̀_•́)ง', '( ͡° ͜ʖ ͡°)', '(⊙_⊙)', '(¬‿¬)', '(>_<)', '(^_^)b', '(; ̄Д ̄)']
return emojis[Math.floor(Math.random() * emojis.length)]
},
getRandomColor() {
const colors = ['#FF4500', '#FF6347', '#FF7F50', '#FF8C00', '#FFA500', '#FFD700']
return colors[Math.floor(Math.random() * colors.length)]
}
}
}
</script>
<style scoped>
.not-found {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #71b7e6, #9b59b6);
font-family: 'Arial', sans-serif;
}
.content {
width: 90%;
max-width: 800px;
background-color: #ffffff;
border-radius: 15px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
padding: 3rem;
position: relative;
z-index: 1;
}
.message {
text-align: center;
margin-bottom: 2rem;
}
.message h1 {
font-size: 3rem;
color: #333;
margin-bottom: 0.5rem;
}
.message p {
font-size: 1.2rem;
color: #666;
}
.game-container {
position: relative;
width: 100%;
height: 300px;
border: 2px solid #ccc;
border-radius: 15px;
overflow: hidden;
background-color: #f9f9f9;
margin-bottom: 1.5rem;
}
.dino, .obstacle {
position: absolute;
font-size: 2.5rem;
line-height: 1;
white-space: nowrap;
}
.dino {
bottom: 20px;
}
.obstacle {
bottom: 20px;
}
.health-bar {
width: 100%;
height: 25px;
background-color: #e0e0e0;
border-radius: 15px;
overflow: hidden;
margin-bottom: 1.5rem;
}
.health {
height: 100%;
background-color: #4CAF50;
border-radius: 15px;
transition: width 0.3s ease-in-out;
}
.instructions {
text-align: center;
font-size: 1.2rem;
color: #666;
margin-bottom: 1.5rem;
}
.home-link {
display: block;
text-align: center;
text-decoration: none;
color: #2196F3;
font-weight: bold;
font-size: 1.2rem;
transition: color 0.3s ease;
}
.home-link:hover {
color: #1565C0;
}
</style>