<h1>貪食蛇遊戲</h1>
<p id="startMessage">按下空白鍵開始遊戲!</p>
<canvas id="gameCanvas" width="400" height="400" style="display:none;"></canvas>
<div id="score" style="display:none;">分數: 0</div>
<audio id="eatSound" src="https://example.com/eat.mp3"></audio>
<audio id="gameOverSound" src="https://example.com/gameover.mp3"></audio>
body {
text-align: center;
}
canvas {
background-color: #eee;
display: block;
margin: 0 auto;
}
#score {
font-size: 24px;
font-family: Arial, sans-serif;
margin-top: 20px;
}
#startMessage {
font-size: 20px;
font-family: Arial, sans-serif;
color: green;
}
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const eatSound = document.getElementById('eatSound');
const gameOverSound = document.getElementById('gameOverSound');
const startMessage = document.getElementById('startMessage');
const scoreDisplay = document.getElementById('score');
const gridSize = 20;
let snake = [{x: 200, y: 200}];
let direction = {x: 0, y: 0}; // 初始方向為靜止
let food = null; // 初始時沒有食物
let score = 0;
let gameStarted = false;
let foodTimer = null; // 控制水果隨機出現的計時器
// 生成隨機食物位置
function generateFood() {
return {
x: Math.floor(Math.random() * canvas.width / gridSize) * gridSize,
y: Math.floor(Math.random() * canvas.height / gridSize) * gridSize
};
}
// 畫出蛇
function drawSnake() {
ctx.fillStyle = 'green';
snake.forEach(segment => {
ctx.fillRect(segment.x, segment.y, gridSize, gridSize);
});
}
// 畫出水果
function drawFood() {
if (food) { // 如果食物存在則繪製
const img = new Image();
img.src = 'https://example.com/fruit.png'; // 請將水果圖像換成您的網址
ctx.drawImage(img, food.x, food.y, gridSize, gridSize);
}
}
// 蛇移動邏輯
function moveSnake() {
const head = {x: snake[0].x + direction.x, y: snake[0].y + direction.y};
snake.unshift(head);
// 吃到食物
if (food && head.x === food.x && head.y === food.y) {
eatSound.play();
score += 10;
scoreDisplay.innerText = '分數: ' + score;
food = null; // 吃掉後水果消失
scheduleNextFood(); // 重新設置隨機時間生成下一個食物
} else {
snake.pop();
}
// 撞到邊界或自己
if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || snake.some((segment, index) => index !== 0 && segment.x === head.x && segment.y === head.y)) {
gameOverSound.play();
alert('遊戲結束!');
resetGame();
}
}
// 遊戲循環
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSnake();
drawFood(); // 只要有食物,持續繪製
moveSnake();
setTimeout(gameLoop, 150);
}
// 重置遊戲
function resetGame() {
snake = [{x: 200, y: 200}];
direction = {x: 0, y: 0}; // 停止
score = 0;
scoreDisplay.innerText = '分數: ' + score;
food = null;
clearTimeout(foodTimer); // 清除計時器
gameStarted = false;
startMessage.style.display = 'block';
canvas.style.display = 'none';
scoreDisplay.style.display = 'none';
}
// 隨機時間安排下一個食物出現
function scheduleNextFood() {
const randomTime = Math.floor(Math.random() * 5000) + 2000; // 在2到7秒之間的隨機時間
foodTimer = setTimeout(() => {
food = generateFood(); // 設置新的食物
}, randomTime);
}
// 等待空白鍵開始遊戲
window.addEventListener('keydown', e => {
if (!gameStarted && e.code === 'Space') {
startMessage.style.display = 'none';
canvas.style.display = 'block';
scoreDisplay.style.display = 'block';
gameStarted = true;
direction = {x: 0, y: -gridSize}; // 設置初始方向為向上
scheduleNextFood(); // 首次啟動隨機生成水果
gameLoop();
}
// 設定蛇移動方向
if (gameStarted) {
switch(e.key) {
case 'ArrowUp':
if (direction.y === 0) direction = {x: 0, y: -gridSize};
break;
case 'ArrowDown':
if (direction.y === 0) direction = {x: 0, y: gridSize};
break;
case 'ArrowLeft':
if (direction.x === 0) direction = {x: -gridSize, y: 0};
break;
case 'ArrowRight':
if (direction.x === 0) direction = {x: gridSize, y: 0};
break;
}
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.