当前位置: 首页 > article >正文

不到200行代码,一键写出简单贪吃蛇网页游戏!附详细代码!快来看看吧!

​哈喽大家好,这里是大白百宝阁,每天分享一段小代码~

今天要分享的是,不到200行代码,制作html版贪吃蛇,效果如下:

游戏结束后,还会显示:

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>贪吃蛇游戏</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      background-color: #333;
    }

    canvas {
      border: 1px solid #fff;
    }
  </style>
</head>
<body>
  <canvas id="gameCanvas" width="400" height="400"></canvas>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    // 常量
    const GRID_SIZE = 20;
    const CELL_SIZE = canvas.width / GRID_SIZE;

    // 蛇的初始化
    let snake = [
      { x: 5, y: 10 },
      { x: 4, y: 10 },
      { x: 3, y: 10 }
    ];

    // 食物的初始化
    let food = {
      x: Math.floor(Math.random() * GRID_SIZE),
      y: Math.floor(Math.random() * GRID_SIZE)
    };

    let direction = 'right';
    let score = 0;
    let gameInterval;
    let gameSpeed = 300;

    // 移动蛇
    function moveSnake() {
      const head = { x: snake[0].x, y: snake[0].y };
      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 === food.x && head.y === food.y) {
        score++;
        generateFood();
        increaseGameSpeed();
      } else {
        snake.pop();
      }

      snake.unshift(head);

      // 检查是否撞到墙壁或自己
      if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE || checkCollision(head)) {
        stopGame();
        alert(`游戏结束! 你的得分是 ${score}`);
        resetGame();
      }
    }

    // 检查蛇头是否撞到自己
    function checkCollision(head) {
      for (let i = 1; i < snake.length; i++) {
        if (head.x === snake[i].x && head.y === snake[i].y) {
          return true;
        }
      }
      return false;
    }

    // 绘制蛇
    function drawSnake() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      drawGrid();
      ctx.fillStyle = '#fff';
      snake.forEach(segment => {
        ctx.fillRect(segment.x * CELL_SIZE, segment.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
      });
    }

    // 绘制食物
    function drawFood() {
      ctx.fillStyle = '#f00';
      ctx.fillRect(food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
    }

    // 绘制网格
    function drawGrid() {
      ctx.strokeStyle = '#444';
      for (let x = 0; x <= canvas.width; x += CELL_SIZE) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, canvas.height);
        ctx.stroke();
      }
      for (let y = 0; y <= canvas.height; y += CELL_SIZE) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(canvas.width, y);
        ctx.stroke();
      }
    }

    // 生成新的食物
    function generateFood() {
      food = {
        x: Math.floor(Math.random() * GRID_SIZE),
        y: Math.floor(Math.random() * GRID_SIZE)
      };
    }

    // 增加游戏速度
    function increaseGameSpeed() {
      gameSpeed = Math.max(gameSpeed - 20, 100);
      stopGame();
      startGame();
    }

    // 重置游戏
    function resetGame() {
      snake = [
        { x: 5, y: 10 },
        { x: 4, y: 10 },
        { x: 3, y: 10 }
      ];
      direction = 'right';
      score = 0;
      gameSpeed = 300;
      generateFood();
      startGame();
    }

    // 开始游戏
    function startGame() {
      gameInterval = setInterval(function() {
        moveSnake();
        drawSnake();
        drawFood();
      }, gameSpeed);
    }

    // 停止游戏
    function stopGame() {
      clearInterval(gameInterval);
    }

    // 监听键盘事件改变蛇的移动方向
    document.addEventListener('keydown', (event) => {
      switch (event.key) {
        case 'ArrowUp':
          if (direction !== 'down') direction = 'up';
          break;
        case 'ArrowDown':
          if (direction !== 'up') direction = 'down';
          break;
        case 'ArrowLeft':
          if (direction !== 'right') direction = 'left';
          break;
        case 'ArrowRight':
          if (direction !== 'left') direction = 'right';
          break;
      }
    });

    // 开始游戏
    resetGame();
  </script>
</body>
</html>

大白会在下一篇文章中,详细解释该代码的运作,并且给出优化UI和性能的方案,关注我,我们在下一篇文章见~


http://www.kler.cn/a/297296.html

相关文章:

  • 分布式锁-缓存一致性问题-失效模式
  • 昔日洗衣液一哥偏执于直播带货市值缩水九成 或成胡干失败样板
  • VScode:前端开发中的常用快捷键和技巧
  • 分享 | 某省级城商行用零信任破解远程访问安全风险
  • 滑动窗口系列(背向双指针)9/8
  • [git操作] git创建仓库上传github报错
  • 并发编程(六)
  • vue3 cookie 存取删数据
  • 镭速助力构筑ICT安全高效的大文件传输
  • 【android10】【binder】【2.servicemanager启动——全源码分析】
  • MySQL数据归档策略:实现定期数据维护与优化
  • 数据结构—单链表的基本操作
  • Vue3进阶:异步状态示例
  • Docker 学习 Day 1
  • springboot整合Logback
  • 千益畅行,共享旅游卡,引领旅游新潮流
  • “Jmeter-InfluxDB-Grafana“常见错误有哪些如何解决?
  • verilog报错:Illegal concatenation of an unsized constant. and 输入输出位宽不匹配
  • 安全服务面试-2
  • Spring Cloud LoadBalancer