canvas实现贪吃蛇

DOCTYPE html>
<html>

<head>
  <title>Canvas贪吃蛇title>
  <style>
    canvas {
      border: 2px solid #333;
    }

    #controlPanel {
      margin: 10px 0;
      display: flex;
      gap: 10px;
    }

    button {
      padding: 8px 16px;
      font-size: 16px;
      cursor: pointer;
      background: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
    }

    button:hover {
      background: #45a049;
    }

    #score {
      font-size: 24px;
      font-family: Arial;
    }
  style>
head>

<body>
  <div id="score">得分: 0div>
  <div id="controlPanel">
    <button id="startBtn">开始游戏button>
    <button id="pauseBtn" disabled>暂停button>
  div>
  <canvas id="gameCanvas" width="400" height="400">canvas>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const startBtn = document.getElementById('startBtn');
    const pauseBtn = document.getElementById('pauseBtn');
    const GRID_SIZE = 20;
    const GRID_COUNT = canvas.width / GRID_SIZE;

    let snake = [];
    let food = {};
    let direction = 'right';
    let nextDirection = 'right';
    let score = 0;
    let gameLoop;
    let isPlaying = false;
    let isPaused = false;

    function initGame() {
      snake = [{ x: 10, y: 10 }];
      food = generateFood();
      direction = 'right';
      nextDirection = 'right';
      score = 0;
      document.getElementById('score').textContent = `得分: ${score}`;
      isPlaying = true;
      isPaused = false;
      pauseBtn.textContent = '暂停';
      pauseBtn.disabled = false;
    }

    function generateFood() {
      while (true) {
        const food = {
          x: Math.floor(Math.random() * GRID_COUNT),
          y: Math.floor(Math.random() * GRID_COUNT)
        };
        if (!snake.some(segment => segment.x === food.x && segment.y === food.y)) {
          return food;
        }
      }
    }

    function update() {
      direction = nextDirection;
      const head = { ...snake[0] };

      switch (direction) {
        case 'up': head.y--; break;
        case 'down': head.y++; break;
        case 'left': head.x--; break;
        case 'right': head.x++; break;
      }

      if (head.x < 0 || head.x >= GRID_COUNT ||
        head.y < 0 || head.y >= GRID_COUNT ||
        snake.some(segment => segment.x === head.x && segment.y === head.y)) {
        gameOver();
        return;
      }

      snake.unshift(head);

      if (head.x === food.x && head.y === food.y) {
        score += 10;
        document.getElementById('score').textContent = `得分: ${score}`;
        food = generateFood();
      } else {
        snake.pop();
      }
    }

    function draw() {
      ctx.fillStyle = '#f0f0f0';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      ctx.fillStyle = '#4CAF50';
      snake.forEach(segment => {
        ctx.fillRect(
          segment.x * GRID_SIZE,
          segment.y * GRID_SIZE,
          GRID_SIZE - 1,
          GRID_SIZE - 1
        );
      });

      ctx.fillStyle = '#ff0000';
      ctx.fillRect(
        food.x * GRID_SIZE,
        food.y * GRID_SIZE,
        GRID_SIZE - 1,
        GRID_SIZE - 1
      );
    }

    function gameOver() {
      clearInterval(gameLoop);
      isPlaying = false;
      pauseBtn.disabled = true;
      alert(`游戏结束!得分: ${score}`);
    }

    function togglePause() {
      isPaused = !isPaused;
      pauseBtn.textContent = isPaused ? '继续' : '暂停';
      if (isPaused) {
        clearInterval(gameLoop);
      } else {
        gameLoop = setInterval(gameStep, 150);
      }
    }

    function gameStep() {
      update();
      draw();
    }

    // 事件监听
    document.addEventListener('keydown', (e) => {
      if (!isPlaying || isPaused) return;

      switch (e.key) {
        case 'ArrowUp':
          if (direction !== 'down') nextDirection = 'up';
          break;
        case 'ArrowDown':
          if (direction !== 'up') nextDirection = 'down';
          break;
        case 'ArrowLeft':
          if (direction !== 'right') nextDirection = 'left';
          break;
        case 'ArrowRight':
          if (direction !== 'left') nextDirection = 'right';
          break;
      }
    });

    startBtn.addEventListener('click', () => {
      if (!isPlaying) {
        initGame();
        gameLoop = setInterval(gameStep, 150);
      }
    });

    pauseBtn.addEventListener('click', togglePause);
  script>
body>

html>

你可能感兴趣的:(JavaScript,css,前端,javascript)