目 录CONTENT

文章目录

JavaScript贪吃蛇游戏

星野集
2026-04-11 / 0 评论 / 0 点赞 / 1 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
眼看十遍,不如手敲一遍!‌ ‌打开控制台‌ ‌Windows/Linux‌:按 F12 或 Ctrl+Shift+I ‌......Mac‌:按 Option+Command+I 也可右键网页 → 选择「检查」→ 切换到「Console」标签 ‌ ......动手实践‌ ▶ 在闪烁的光标处直接输入教程代码 ▶ 按 Enter 执行代码,立即看到结果 ▶ 用 ↑↓ 方向键快速调出历史命令 ......当需要编写多行代码时: 正常输入第一行代码 按住 Ctrl 键(Mac用户按 Command) 再按 Enter 换行而不执行 代码输入完成后,单独按 Enter 执行全部 ‌.......小技巧‌ 输入 clear() 可清空控制台 错误提示是好朋友!红色报错能帮你快速定位问题 💡 记住:每个程序员都从这里开始你的第一行代码吧! ⚠️ 注意:部分旧版浏览器可能不支持此功能,建议使用Chrome/Edge/Firefox最新版

贪吃蛇是一款经典的休闲游戏,它不仅简单易玩,而且是学习JavaScript和Canvas API的绝佳例子。今天,我们将学习如何使用JavaScript和Canvas API实现一个完整的贪吃蛇游戏,包括蛇的移动、食物生成、碰撞检测和游戏控制。

游戏概述

贪吃蛇游戏的基本规则很简单:玩家控制一条蛇在游戏区域内移动,吃掉随机生成的食物,每吃一次食物蛇的身体就会变长,当蛇撞到墙壁或自身时游戏结束。

我们的实现将包括以下功能:

  • 蛇的移动和身体增长
  • 随机食物生成
  • 碰撞检测(墙壁和自身)
  • 游戏结束和重新开始
  • 分数计算

实现原理

我们将使用HTML5 Canvas API来绘制游戏画面,使用JavaScript来处理游戏逻辑。游戏的核心是一个主循环,它不断更新蛇的位置、检测碰撞、绘制游戏画面。

主要实现步骤:

  1. 创建Canvas元素并获取绘图上下文
  2. 初始化游戏变量(蛇的位置、方向、食物位置等)
  3. 实现游戏主循环(移动蛇、检测碰撞、绘制画面)
  4. 处理键盘事件,控制蛇的移动方向
  5. 实现游戏结束和重新开始功能

核心代码

以下是贪吃蛇游戏的核心代码,包括游戏初始化、蛇的移动、碰撞检测和绘制函数:

function initSnakeGame() {
    const canvas = document.getElementById('snakeCanvas');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    
    // 设置画布大小
    canvas.width = 400;
    canvas.height = 400;
    
    // 游戏参数
    const gridSize = 20;
    const snake = [
        { x: 10, y: 10 },
        { x: 9, y: 10 },
        { x: 8, y: 10 }
    ];
    let food = { x: 15, y: 15 };
    let direction = 'right';
    let gameOver = false;
    let gameSpeed = 150; // 游戏速度(毫秒)
    let lastMoveTime = 0;
    let gameLoopId = null;
    
    // 绘制蛇
    function drawSnake() {
        snake.forEach(segment => {
            ctx.fillStyle = '#4CAF50';
            ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
            ctx.strokeStyle = '#388E3C';
            ctx.strokeRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
        });
    }
    
    // 绘制食物
    function drawFood() {
        ctx.fillStyle = '#F44336';
        ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
    }
    
    // 移动蛇
    function moveSnake() {
        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;
        }
        
        // 将新头部添加到蛇的前面
        snake.unshift(head);
        
        // 检查是否吃到食物
        if (head.x === food.x && head.y === food.y) {
            // 生成新食物
            generateFood();
        } else {
            // 移除尾部
            snake.pop();
        }
        
        // 检查碰撞
        checkCollision();
    }
    
    // 生成食物
    function generateFood() {
        food = {
            x: Math.floor(Math.random() * (canvas.width / gridSize)),
            y: Math.floor(Math.random() * (canvas.height / gridSize))
        };
        
        // 确保食物不在蛇身上
        snake.forEach(segment => {
            if (segment.x === food.x && segment.y === food.y) {
                generateFood();
            }
        });
    }
    
    // 检查碰撞
    function checkCollision() {
        const head = snake[0];
        
        // 检查边界碰撞
        if (head.x < 0 || head.x >= canvas.width / gridSize || 
            head.y < 0 || head.y >= canvas.height / gridSize) {
            gameOver = true;
        }
        
        // 检查自身碰撞
        for (let i = 1; i < snake.length; i++) {
            if (head.x === snake[i].x && head.y === snake[i].y) {
                gameOver = true;
            }
        }
    }
    
    // 绘制游戏
    function drawGame() {
        // 清空画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        if (!gameOver) {
            const currentTime = Date.now();
            if (currentTime - lastMoveTime >= gameSpeed) {
                moveSnake();
                lastMoveTime = currentTime;
            }
            drawSnake();
            drawFood();
            gameLoopId = requestAnimationFrame(drawGame);
        } else {
            // 游戏结束
            ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = 'white';
            ctx.font = '24px Arial';
            ctx.textAlign = 'center';
            ctx.fillText('游戏结束', canvas.width / 2, canvas.height / 2);
            ctx.font = '16px Arial';
            ctx.fillText('按空格键重新开始', canvas.width / 2, canvas.height / 2 + 30);
        }
    }
    
    // 处理键盘事件
    const snakeContainer = document.querySelector('.code-crazy-snake-container');
    
    // 为游戏容器添加点击事件,使其获得焦点
    snakeContainer.addEventListener('click', function() {
        snakeContainer.focus();
    });
    
    // 为游戏容器添加键盘事件
    snakeContainer.addEventListener('keydown', function(e) {
        // 阻止所有游戏相关按键的默认行为(防止页面滚动)
        if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(e.key)) {
            e.preventDefault();
            e.stopPropagation();
        }
        
        switch (e.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;
            case ' ': // 空格键重新开始
                if (gameOver) {
                    // 重置游戏
                    snake.length = 0;
                    snake.push({ x: 10, y: 10 });
                    snake.push({ x: 9, y: 10 });
                    snake.push({ x: 8, y: 10 });
                    direction = 'right';
                    gameOver = false;
                    generateFood();
                    drawGame();
                }
                break;
        }
    });
    
    // 开始游戏
    generateFood();
    drawGame();
}

游戏演示

下面是贪吃蛇游戏的实时演示,你可以点击游戏区域后使用方向键控制蛇的移动,按空格键重新开始游戏。

点击游戏区域后使用方向键控制蛇的移动,空格键重新开始游戏

如何使用

要在你的项目中使用这个贪吃蛇游戏,只需按照以下步骤操作:

  1. 将上述JavaScript函数添加到你的脚本中
  2. 添加必要的CSS样式:
.code-crazy-snake-container {
    margin-top: 20px;
    text-align: center;
    outline: none;
}

.code-crazy-snake-container:focus {
    outline: 2px solid #6b8cff;
    border-radius: 4px;
}

#snakeCanvas {
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #f8f8f8;
    cursor: pointer;
}

.code-crazy-snake-hint {
    margin-top: 10px;
    font-size: 14px;
    color: #666;
}
  1. 在HTML中创建Canvas元素:
<div class="code-crazy-snake-container" tabindex="0">
    <canvas id="snakeCanvas"></canvas>
    <p class="code-crazy-snake-hint">点击游戏区域后使用方向键控制蛇的移动,空格键重新开始游戏</p>
</div>
  1. 调用initSnakeGame函数:
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
    initSnakeGame();
});

游戏扩展

你可以通过以下方式扩展贪吃蛇游戏:

  • 增加难度级别:随着分数增加,蛇的移动速度逐渐加快
  • 添加障碍物:在游戏区域内随机生成障碍物
  • 实现分数系统:记录并显示最高分数
  • 添加音效:为吃食物、碰撞等事件添加音效
  • 美化游戏界面:添加背景图片、粒子效果等
  • 实现多人模式:添加局域网或在线 multiplayer 功能

技术要点

实现贪吃蛇游戏涉及以下技术要点:

  • Canvas API:用于绘制游戏画面
  • JavaScript定时器:用于控制游戏主循环
  • 事件处理:处理键盘输入
  • 数组操作:管理蛇的身体 segments
  • 碰撞检测:检测蛇与墙壁、自身的碰撞
  • 随机数生成:生成随机的食物位置

总结

JavaScript贪吃蛇游戏是一个很好的学习项目,它涵盖了前端开发中的许多重要概念,如Canvas绘图、事件处理、游戏循环和碰撞检测。通过实现这个游戏,你可以提高你的JavaScript编程技能,同时了解游戏开发的基本原理。

这个实现虽然简单,但已经包含了贪吃蛇游戏的核心功能。你可以根据自己的兴趣和技能水平,进一步扩展和美化这个游戏,创造出属于你自己的版本。

0
  1. 微信打赏

    qrcode weixin
    1. 微信打赏

      qrcode weixin

评论区