<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;
        }
    }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.