game / index.html
juzi
Add 2 files
e5f422b verified
Raw
History Blame Contribute Delete
20.7 kB
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小蜜蜂吃果子</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: #87CEEB;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
position: relative;
background-image: linear-gradient(to bottom, #87CEEB, #E0F7FA);
}
.game-container {
position: relative;
width: 800px;
height: 500px;
border: 3px solid #FF9800;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
overflow: hidden;
background-color: #E0F7FA;
}
canvas {
display: block;
background-color: #E0F7FA;
}
.welcome-screen, .game-over-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.7);
color: white;
z-index: 10;
}
.game-over-screen {
display: none;
}
h1 {
font-size: 36px;
margin-bottom: 20px;
color: #FFEB3B;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
p {
font-size: 18px;
margin-bottom: 30px;
max-width: 80%;
text-align: center;
}
button {
background-color: #FF9800;
color: white;
border: none;
padding: 12px 30px;
font-size: 18px;
border-radius: 30px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
button:hover {
background-color: #FF5722;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
.score-display {
position: absolute;
top: 20px;
left: 20px;
font-size: 24px;
color: #333;
background-color: rgba(255, 255, 255, 0.8);
padding: 10px 20px;
border-radius: 10px;
display: flex;
align-items: center;
z-index: 5;
}
.score-display span {
margin-left: 10px;
font-weight: bold;
color: #FF9800;
}
.controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(255, 255, 255, 0.8);
padding: 10px 20px;
border-radius: 10px;
font-size: 16px;
color: #333;
}
@keyframes cloudMove {
from { transform: translateX(800px); }
to { transform: translateX(-200px); }
}
.cloud {
position: absolute;
color: white;
font-size: 80px;
animation: cloudMove linear infinite;
z-index: 0;
opacity: 0.8;
user-select: none;
}
.cloud:nth-child(1) {
top: 50px;
animation-duration: 40s;
}
.cloud:nth-child(2) {
top: 150px;
animation-duration: 50s;
animation-delay: -15s;
}
.cloud:nth-child(3) {
top: 300px;
animation-duration: 60s;
animation-delay: -30s;
}
.sound-control {
position: absolute;
top: 20px;
right: 20px;
background-color: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 50%;
cursor: pointer;
z-index: 5;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
}
.sound-control i {
font-size: 20px;
color: #333;
}
/* Flower decorations */
.flower {
position: absolute;
font-size: 40px;
color: #FF5722;
bottom: -10px;
z-index: 1;
user-select: none;
}
.flower:nth-child(1) {
left: 100px;
}
.flower:nth-child(2) {
right: 150px;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
</head>
<body>
<!-- Cloud decorations -->
<div class="cloud">☁️</div>
<div class="cloud">☁️</div>
<div class="cloud">☁️</div>
<!-- Flower decorations -->
<div class="flower">🌻</div>
<div class="flower">🌼</div>
<div class="game-container">
<div class="score-display">
分数: <span id="score">0</span>
</div>
<div class="sound-control" id="soundControl">
<i class="fas fa-volume-up"></i>
</div>
<div class="welcome-screen" id="welcomeScreen">
<h1>小蜜蜂吃果子</h1>
<p>帮助可爱的小蜜蜂收集甜蜜的花粉果实!使用键盘方向键控制小蜜蜂移动,避开障碍物,吃到越多果实得分越高!</p>
<button id="startBtn">开始游戏</button>
</div>
<div class="game-over-screen" id="gameOverScreen">
<h1>游戏结束!</h1>
<p>你的最终分数是: <span id="finalScore">0</span></p>
<button id="restartBtn">再来一次</button>
</div>
<canvas id="gameCanvas" width="800" height="500"></canvas>
</div>
<div class="controls">
使用键盘方向键(↑↓←→)控制小蜜蜂移动
</div>
<script>
// 游戏状态
const gameState = {
score: 0,
gameOver: false,
soundEnabled: true,
gameSpeed: 3,
difficultyIncreaseInterval: 10, // 每10个果实增加难度
lastDifficultyIncrease: 0
};
// DOM元素
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const finalScoreDisplay = document.getElementById('finalScore');
const welcomeScreen = document.getElementById('welcomeScreen');
const gameOverScreen = document.getElementById('gameOverScreen');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const soundControl = document.getElementById('soundControl');
// 游戏元素
const bee = {
x: canvas.width / 2,
y: canvas.height / 2,
size: 40,
speed: 5
};
const fruits = [];
const obstacles = [];
let fruitSpawnTimer = 0;
let obstacleSpawnTimer = 0;
// 按键状态
const keys = {
ArrowUp: false,
ArrowDown: false,
ArrowLeft: false,
ArrowRight: false
};
// 加载音效
const sounds = {
collect: new Audio('data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU...'), // 简短的收集音效
gameOver: new Audio('data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU...') // 简短的结束音效
};
// 监听按键事件
window.addEventListener('keydown', (e) => {
if (keys.hasOwnProperty(e.key)) {
keys[e.key] = true;
e.preventDefault();
}
});
window.addEventListener('keyup', (e) => {
if (keys.hasOwnProperty(e.key)) {
keys[e.key] = false;
e.preventDefault();
}
});
// 开始游戏按钮
startBtn.addEventListener('click', () => {
welcomeScreen.style.display = 'none';
resetGame();
gameLoop();
});
// 重新开始按钮
restartBtn.addEventListener('click', () => {
gameOverScreen.style.display = 'none';
resetGame();
gameLoop();
});
// 音效控制
soundControl.addEventListener('click', () => {
gameState.soundEnabled = !gameState.soundEnabled;
soundControl.innerHTML = gameState.soundEnabled ?
'<i class="fas fa-volume-up"></i>' : '<i class="fas fa-volume-mute"></i>';
});
// 重置游戏
function resetGame() {
gameState.score = 0;
gameState.gameOver = false;
gameState.gameSpeed = 3;
gameState.lastDifficultyIncrease = 0;
scoreDisplay.textContent = '0';
bee.x = canvas.width / 2;
bee.y = canvas.height / 2;
fruits.length = 0;
obstacles.length = 0;
fruitSpawnTimer = 0;
obstacleSpawnTimer = 0;
}
// 绘制蜜蜂
function drawBee() {
// 蜜蜂身体
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(bee.x, bee.y, bee.size / 2, 0, Math.PI * 2);
ctx.fill();
// 黑色条纹
ctx.strokeStyle = '#333';
ctx.lineWidth = 3;
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.arc(bee.x, bee.y, bee.size / 2 - 5, Math.PI * 0.2 + i * Math.PI * 0.5, Math.PI * 0.8 + i * Math.PI * 0.5);
ctx.stroke();
}
// 翅膀
ctx.fillStyle = 'rgba(200, 200, 255, 0.7)';
ctx.beginPath();
ctx.ellipse(bee.x - bee.size * 0.3, bee.y - bee.size * 0.3, bee.size * 0.3, bee.size * 0.5, Math.PI / 4, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.ellipse(bee.x + bee.size * 0.3, bee.y - bee.size * 0.3, bee.size * 0.3, bee.size * 0.5, -Math.PI / 4, 0, Math.PI * 2);
ctx.fill();
// 眼睛
ctx.fillStyle = '#333';
ctx.beginPath();
ctx.arc(bee.x + bee.size * 0.15, bee.y - bee.size * 0.15, bee.size * 0.1, 0, Math.PI * 2);
ctx.fill();
// 触角
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(bee.x + bee.size * 0.15, bee.y - bee.size * 0.2);
ctx.lineTo(bee.x + bee.size * 0.3, bee.y - bee.size * 0.4);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(bee.x - bee.size * 0.15, bee.y - bee.size * 0.2);
ctx.lineTo(bee.x - bee.size * 0.3, bee.y - bee.size * 0.4);
ctx.stroke();
}
// 创建果实
function spawnFruit() {
const size = Math.random() * 20 + 15;
const x = Math.random() * (canvas.width - size);
const y = Math.random() * (canvas.height - size);
const type = Math.floor(Math.random() * 3); // 3种不同类型的果实
fruits.push({
x,
y,
size,
type,
speedY: Math.random() * 1 + 0.5
});
}
// 创建障碍物
function spawnObstacle() {
const width = Math.random() * 80 + 50;
const height = Math.random() * 80 + 30;
const x = Math.random() > 0.5 ? -width : canvas.width;
const y = Math.random() * (canvas.height - height);
obstacles.push({
x,
y,
width,
height,
speedX: (Math.random() * 2 + 2) * (x < 0 ? 1 : -1),
rotation: Math.random() * Math.PI * 2,
rotationSpeed: (Math.random() - 0.5) * 0.1
});
}
// 绘制果实
function drawFruits() {
fruits.forEach((fruit, index) => {
// 位置更新
fruit.y += fruit.speedY;
// 超出屏幕移除
if (fruit.y > canvas.height + fruit.size) {
fruits.splice(index, 1);
return;
}
// 根据类型绘制不同果实
switch (fruit.type) {
case 0: // 红色果子
ctx.fillStyle = '#FF5252';
break;
case 1: // 黄色果子
ctx.fillStyle = '#FFD740';
break;
case 2: // 紫色果子
ctx.fillStyle = '#9C27B0';
break;
}
// 绘制果实
ctx.beginPath();
ctx.arc(fruit.x + fruit.size / 2, fruit.y + fruit.size / 2, fruit.size / 2, 0, Math.PI * 2);
ctx.fill();
// 绘制果实顶部
ctx.fillStyle = '#8BC34A';
ctx.beginPath();
ctx.moveTo(fruit.x + fruit.size / 2 - fruit.size * 0.2, fruit.y + fruit.size * 0.2);
ctx.lineTo(fruit.x + fruit.size / 2 + fruit.size * 0.1, fruit.y + fruit.size * 0.1);
ctx.lineTo(fruit.x + fruit.size / 2, fruit.y);
ctx.fill();
});
}
// 绘制障碍物
function drawObstacles() {
obstacles.forEach((obstacle, index) => {
// 位置更新
obstacle.x += obstacle.speedX;
obstacle.y += Math.sin(Date.now() / 300) * 0.5; // 上下浮动效果
obstacle.rotation += obstacle.rotationSpeed;
// 超出屏幕移除
if ((obstacle.speedX > 0 && obstacle.x > canvas.width) ||
(obstacle.speedX < 0 && obstacle.x + obstacle.width < 0)) {
obstacles.splice(index, 1);
return;
}
ctx.save();
ctx.translate(obstacle.x + obstacle.width / 2, obstacle.y + obstacle.height / 2);
ctx.rotate(obstacle.rotation);
// 障碍物形状
ctx.fillStyle = '#795548';
ctx.beginPath();
ctx.moveTo(-obstacle.width / 2, -obstacle.height / 2);
ctx.lineTo(obstacle.width / 2, -obstacle.height / 2 - 10);
ctx.lineTo(obstacle.width / 2 + 10, obstacle.height / 2);
ctx.lineTo(-obstacle.width / 2 + 10, obstacle.height / 2);
ctx.closePath();
ctx.fill();
// 障碍物细节
ctx.fillStyle = '#5D4037';
ctx.beginPath();
ctx.arc(-obstacle.width / 4, -obstacle.height / 4, 5, 0, Math.PI * 2);
ctx.arc(obstacle.width / 4, -obstacle.height / 4, 5, 0, Math.PI * 2);
ctx.arc(obstacle.width / 4, obstacle.height / 4, 5, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
});
}
// 检测碰撞
function checkCollisions() {
// 检测蜜蜂与果实的碰撞
fruits.forEach((fruit, index) => {
const dx = bee.x - (fruit.x + fruit.size / 2);
const dy = bee.y - (fruit.y + fruit.size / 2);
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < bee.size / 2 + fruit.size / 2) {
// 碰撞发生
if (gameState.soundEnabled) {
sounds.collect.currentTime = 0;
sounds.collect.play().catch(e => {});
}
gameState.score += 10;
scoreDisplay.textContent = gameState.score;
fruits.splice(index, 1);
// 根据得分增加难度
if (gameState.score - gameState.lastDifficultyIncrease >= gameState.difficultyIncreaseInterval) {
gameState.gameSpeed += 0.5;
gameState.lastDifficultyIncrease = gameState.score;
}
}
});
// 检测蜜蜂与障碍物的碰撞
obstacles.forEach(obstacle => {
// 简化为矩形碰撞检测
if (bee.x + bee.size / 2 > obstacle.x &&
bee.x - bee.size / 2 < obstacle.x + obstacle.width &&
bee.y + bee.size / 2 > obstacle.y &&
bee.y - bee.size / 2 < obstacle.y + obstacle.height) {
if (gameState.soundEnabled) {
sounds.gameOver.currentTime = 0;
sounds.gameOver.play().catch(e => {});
}
gameState.gameOver = true;
gameOverScreen.style.display = 'flex';
finalScoreDisplay.textContent = gameState.score;
}
});
}
// 游戏循环
function gameLoop() {
if (gameState.gameOver) return;
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 更新蜜蜂位置
if (keys.ArrowUp && bee.y > bee.size / 2) {
bee.y -= bee.speed;
}
if (keys.ArrowDown && bee.y < canvas.height - bee.size / 2) {
bee.y += bee.speed;
}
if (keys.ArrowLeft && bee.x > bee.size / 2) {
bee.x -= bee.speed;
}
if (keys.ArrowRight && bee.x < canvas.width - bee.size / 2) {
bee.x += bee.speed;
}
// 生成果实和障碍物
fruitSpawnTimer++;
if (fruitSpawnTimer > 60 / gameState.gameSpeed) { // 控制果实生成速度
spawnFruit();
fruitSpawnTimer = 0;
// 偶尔同时生成多个果实
if (Math.random() < 0.3) {
for (let i = 0; i < 2; i++) {
setTimeout(spawnFruit, i * 300);
}
}
}
obstacleSpawnTimer++;
if (obstacleSpawnTimer > 100 / gameState.gameSpeed) { // 控制障碍物生成速度
spawnObstacle();
obstacleSpawnTimer = 0;
}
// 绘制游戏元素
drawFruits();
drawObstacles();
drawBee();
// 检测碰撞
checkCollisions();
// 继续游戏循环
requestAnimationFrame(gameLoop);
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
</html>