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

HTML贪吃蛇游戏

文章目录

      • 贪吃蛇游戏
    • 运行效果
    • 代码


贪吃蛇游戏

贪吃蛇是一款经典的休闲益智游戏。本文将通过HTML5和JavaScript详细解析如何实现一个简易版的贪吃蛇游戏。游戏的主要逻辑包括蛇的移动、碰撞检测、食物生成等功能。以下是游戏的完整代码及注释解析。(纯属好玩)

运行效果

在这里插入图片描述

代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snake Game</title>
    <style>
        body {
            margin: 0;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #000;
        }

        canvas {
            border: 1px solid #fff;
        }

        .mobile-controls {
            display: flex;
            justify-content: center;
            margin-top: 20px;
        }

        .control-button {
            background-color: #fff;
            border: 1px solid #000;
            padding: 10px 20px;
            margin: 5px;
            font-size: 18px;
            cursor: pointer;
            border-radius: 5px;
        }
    </style>
</head>

<body>

    <!-- 画布,用于绘制蛇和食物 -->
    <canvas id="gameCanvas"></canvas>

    <!-- 控制按钮:上下左右,用于移动蛇 -->
    <div class="mobile-controls">
        <button class="control-button" id="left"></button>
        <button class="control-button" id="up"></button>
        <button class="control-button" id="down"></button>
        <button class="control-button" id="right"></button>
    </div>

    <script>
        // 获取画布和上下文
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // 设置每个方块的大小和游戏区域的行列数
        const scale = 20;
        const rows = 20;
        const columns = 20;

        // 设置画布的宽高
        canvas.width = columns * scale;
        canvas.height = rows * scale;

        let snake;  // 蛇对象
        let food;   // 食物位置
        let direction = { x: 1, y: 0 };  // 方向,初始为向右
        let isGameOver = false;  // 判断游戏是否结束

        // 蛇的构造函数
        function Snake() {
            this.body = [{ x: 10, y: 10 }];  // 蛇的初始位置(数组,每一节为一个坐标)
            
            // 绘制蛇
            this.draw = function () {
                ctx.fillStyle = 'green';  // 设置蛇的颜色为绿色
                for (let i = 0; i < this.body.length; i++) {
                    ctx.fillRect(this.body[i].x * scale, this.body[i].y * scale, scale, scale);  // 绘制蛇的每一节
                }
            };

            // 更新蛇的位置
            this.update = function () {
                // 新的蛇头位置,根据当前方向生成
                const newHead = {
                    x: this.body[0].x + direction.x,
                    y: this.body[0].y + direction.y
                };

                // 判断蛇是否撞墙或撞到自己
                if (newHead.x < 0 || newHead.x >= columns || newHead.y < 0 || newHead.y >= rows || this.isCollision(newHead)) {
                    isGameOver = true;  // 如果碰撞,游戏结束
                }

                // 将新头部添加到蛇的身体
                this.body.unshift(newHead);

                // 如果蛇头吃到食物,生成新的食物
                if (newHead.x === food.x && newHead.y === food.y) {
                    generateFood();
                } else {
                    // 否则,移除蛇尾,保持蛇的长度
                    this.body.pop();
                }
            };

            // 判断是否撞到自己
            this.isCollision = function (pos) {
                for (let i = 0; i < this.body.length; i++) {
                    if (this.body[i].x === pos.x && this.body[i].y === pos.y) {
                        return true;
                    }
                }
                return false;
            };
        }

        // 生成食物的位置,随机在网格中生成
        function generateFood() {
            food = {
                x: Math.floor(Math.random() * columns),
                y: Math.floor(Math.random() * rows)
            };
        }

        // 绘制食物
        function drawFood() {
            ctx.fillStyle = 'red';  // 食物颜色为红色
            ctx.fillRect(food.x * scale, food.y * scale, scale, scale);  // 绘制食物
        }

        // 游戏主循环
        function gameLoop() {
            if (isGameOver) {
                alert('Game Over');  // 游戏结束提示
                document.location.reload();  // 重新加载页面,重新开始游戏
                return;
            }

            // 清空画布,绘制新的状态
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            snake.update();  // 更新蛇的位置
            snake.draw();  // 绘制蛇
            drawFood();  // 绘制食物

            // 每200毫秒更新一次游戏状态
            setTimeout(gameLoop, 200);  
        }

        // 键盘事件监听,使用中文“上、下、左、右”控制蛇的方向
        window.addEventListener('keydown', (e) => {
            switch (e.key) {
                case '上':
                    if (direction.y === 0) direction = { x: 0, y: -1 };  // 向上
                    break;
                case '下':
                    if (direction.y === 0) direction = { x: 0, y: 1 };  // 向下
                    break;
                case '左':
                    if (direction.x === 0) direction = { x: -1, y: 0 };  // 向左
                    break;
                case '右':
                    if (direction.x === 0) direction = { x: 1, y: 0 };  // 向右
                    break;
            }
        });

        // 按钮点击事件,控制蛇的移动方向
        document.getElementById('left').addEventListener('click', () => {
            if (direction.x === 0) direction = { x: -1, y: 0 };
        });

        document.getElementById('right').addEventListener('click', () => {
            if (direction.x === 0) direction = { x: 1, y: 0 };
        });

        document.getElementById('up').addEventListener('click', () => {
            if (direction.y === 0) direction = { x: 0, y: -1 };
        });

        document.getElementById('down').addEventListener('click', () => {
            if (direction.y === 0) direction = { x: 0, y: 1 };
        });

        // 初始化蛇和食物
        snake = new Snake();
        generateFood();
        gameLoop();  // 开始游戏
    </script>

</body>

</html>

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

相关文章:

  • docker构建jdk11
  • 设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
  • Mac intel 安装IDEA激活时遇到问题 jetbrains.vmoptions.plist: Permission denied
  • (干货)Jenkins使用kubernetes插件连接k8s的认证方式
  • 2411C++,C++26反射示例
  • 11张思维导图带你快速学习java
  • 【Spring Boot】SpringBoot自动装配-Import
  • CenterPoint-KITTI:环境配置、模型训练、效果展示;KITTI 3D 目标检测数据集下载
  • 寄存器的位数据调测方法(摩尔信使MThings)
  • Axure科技感大屏系统设计:智慧农场管理平台
  • SCRM电商管理后台Axure高保真原型 源文件
  • 浅谈为什么数据库要用B树
  • 爬虫全网抓取
  • 大众萨克森:SNP助力汽车制造智能化,实现SAP S/4HANA系统成功升级
  • 店群合一模式下的社区团购新发展——结合链动 2+1 模式、AI 智能名片与 S2B2C 商城小程序源码
  • LeetCode509:斐波那契数列
  • 4.C_数据结构_队列
  • Java异常处理详细讲解及常见面试问题
  • 无人机巡检:突破传统局限,引领智能监测新时代
  • java 网络编程URL与URLConnection的使用
  • 深入解析 Apache Ranger
  • 电容的不同材质对应的温度范围
  • Redis主要问题(缓存问题)
  • pyflink 安装和测试
  • Matlab simulink建模与仿真 第十四章(信号输出库)
  • 计算机毕业设计 智慧物业服务系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试