使用js和canvas实现简单的网页贪吃蛇小游戏

玩法介绍

点击开始游戏后,使用键盘上的↑↓←→控制移动,吃到食物增加长度,碰到墙壁或碰到自身就游戏结束

代码实现

代码比较简单,直接阅读注释即可,复制即用

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Snake Game</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
            background-color: #000;
        }
        .start-screen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            text-align: center;
            z-index: 2;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
        }
        button {
            font-size: 24px;
            padding: 10px 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="start-screen">
        <h1>Snake Game</h1>
        <button id="startButton">Start Game</button>
    </div>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // 设置 Canvas 为全屏
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // 方块大小
        const blockSize = 20;

        // 游戏状态
        let snake = [{ x: 100, y: 100 }];
        let food = { x: 200, y: 200 };
        let direction = 'right';
        let score = 0;
        let isRunning = false;

        // 游戏速度
        const speed = 100;

        // 绘制蛇
        function drawSnake() {
            ctx.fillStyle = '#0f0';
            snake.forEach(segment => {
                ctx.fillRect(segment.x, segment.y, blockSize, blockSize);
            });
        }

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

        // 检查碰撞
        function checkCollision() {
            // 检查蛇是否撞墙
            if (snake[0].x < 0 || snake[0].x >= canvas.width || snake[0].y < 0 || snake[0].y >= canvas.height) {
                alert('Game Over!');
                isRunning = false;
                return;
            }

            // 检查蛇是否撞到自己
            for (let i = 1; i < snake.length; i++) {
                if (snake[0].x === snake[i].x && snake[0].y === snake[i].y) {
                    alert('Game Over!');
                    isRunning = false;
                    return;
                }
            }

            // 检查蛇是否吃到食物
            if (snake[0].x === food.x && snake[0].y === food.y) {
                score++;
                placeFood();
            } else {
                snake.pop();
            }
        }

        // 放置新的食物
        function placeFood() {
            food = {
                x: Math.floor(Math.random() * (canvas.width / blockSize)) * blockSize,
                y: Math.floor(Math.random() * (canvas.height / blockSize)) * blockSize
            };
        }

        // 更新游戏状态
        function update() {
            if (!isRunning) return;

            let newX = snake[0].x;
            let newY = snake[0].y;

            if (direction === 'left') newX -= blockSize;
            if (direction === 'right') newX += blockSize;
            if (direction === 'up') newY -= blockSize;
            if (direction === 'down') newY += blockSize;

            snake.unshift({ x: newX, y: newY });

            checkCollision();
        }

        // 渲染游戏画面
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            drawSnake();
            drawFood();
        }

        // 游戏主循环
        function gameLoop() {
            update();
            draw();
            setTimeout(gameLoop, speed);
        }

        // 键盘事件
        function handleKeyPress(event) {
            if (event.key === 'ArrowLeft' && direction !== 'right') direction = 'left';
            if (event.key === 'ArrowRight' && direction !== 'left') direction = 'right';
            if (event.key === 'ArrowUp' && direction !== 'down') direction = 'up';
            if (event.key === 'ArrowDown' && direction !== 'up') direction = 'down';
        }

        // 开始按钮事件
        document.getElementById('startButton').addEventListener('click', () => {
            const startScreen = document.querySelector('.start-screen');
            startScreen.style.display = 'none';

            // 添加键盘事件监听
            document.addEventListener('keydown', handleKeyPress);

            isRunning = true;
            placeFood();
            gameLoop();
        });

        // 游戏结束时移除键盘事件监听
        window.addEventListener('beforeunload', () => {
            document.removeEventListener('keydown', handleKeyPress);
        });
    </script>
</body>
</html>
相关推荐
_丿丨丨_5 小时前
XSS(跨站脚本攻击)
前端·网络·xss
天天进步20155 小时前
前端安全指南:防御XSS与CSRF攻击
前端·安全·xss
呼啦啦呼啦啦啦啦啦啦6 小时前
利用pdfjs实现的pdf预览简单demo(包含翻页功能)
android·javascript·pdf
拾光拾趣录7 小时前
括号生成算法
前端·算法
拾光拾趣录8 小时前
requestIdleCallback:让你的网页如丝般顺滑
前端·性能优化
前端 贾公子8 小时前
vue-cli 模式下安装 uni-ui
前端·javascript·windows
拾光拾趣录8 小时前
链表合并:双指针与递归
前端·javascript·算法
@大迁世界8 小时前
前端:优秀架构的坟墓
前端·架构
拼图2098 小时前
element-plus——图标推荐
javascript·vue.js·elementui
期待のcode8 小时前
图片上传实现
java·前端·javascript·数据库·servlet·交互