HTML贪吃蛇游戏

news2024/9/23 15:42:36

文章目录

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


贪吃蛇游戏

贪吃蛇是一款经典的休闲益智游戏。本文将通过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.coloradmin.cn/o/2138711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (347)-- 算法导论23.2 6题

六、假定一个图中所有的边权重均匀分布在半开区间[0,1)内。Prim算法和Kruskal算法哪一个可以运行得更快&#xff1f;如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 在比较Prim算法和Kruskal算法在特定条件下的性能时&#xff0c;我们需要考虑几个因素&#xff…

【大模型专栏—进阶篇】智能对话全总结

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

C语言 | Leetcode C语言题解之第400题第N位数字

题目&#xff1a; 题解&#xff1a; //解题思路&#xff1a;计算当前已经经过了多少位&#xff0c;当第一次超过n时&#xff0c;开始获取第n位 int findNthDigit(int n){int i, j, tem_1 10, tem_2 1, res; long count 0; /*i和j用于循环&#xff0c;count用…

Spring Boot集成Akka Cluster快速入门Demo

1.什么是Akka Cluster&#xff1f; Akka Cluster将多个JVM连接整合在一起&#xff0c;实现消息地址的透明化和统一化使用管理&#xff0c;集成一体化的消息驱动系统。最终目的是将一个大型程序分割成若干子程序&#xff0c;部署到很多JVM上去实现程序的分布式并行运算&#xf…

【计网】从零开始使用UDP进行socket编程 --- 服务端业务实现

在我们每个人都曾经历过“沮丧”时刻里&#xff0c; 如果我们不能对别人说有益的好话&#xff0c; 那我们最好还是什么也别说。 --- 卡耐基 《人性的弱点》--- 从零开始使用UDP进行socket编程 1 前情提要2 单词翻译2.1 业务需求2.2 设计字典类2.3 服务端与客户端逻辑2.4 运…

SQLite安装(含安装包)

安装包&#xff1a; 通过百度网盘分享的文件&#xff1a;sqlite-dll-win-x64-3460100.zip 链接&#xff1a;https://pan.baidu.com/s/1852coiq51QcNkeaHdu1Oyg 提取码&#xff1a;v2y6 解压 设置环境变量 验证安装成功 SQLite设置完成

ros学习笔记.4 Path Planning Part 2 (避障)

避障是如何工作的什么是局部规划器&#xff1f;什么是局部成本图&#xff1f;路径规划回顾如何使用动态重新配置和其他 Rviz 工具 局部规划器 一旦全局规划器计算出要遵循的路径&#xff0c;该路径就会发送给局部规划器。然后&#xff0c;局部规划器将执行全局规划的每个部分&…

唯徳知识产权管理系统 DownloadFileWordTemplate 文件读取漏洞复现

0x01 产品简介 唯徳知识产权管理系统,由深圳市唯德科创信息有限公司精心打造,旨在为企业及代理机构提供全方位、高效、安全的知识产权管理解决方案。该系统集成了专利、商标、版权等知识产权的全面管理功能,并通过云平台实现远程在线办公,提升工作效率。是一款集知识产权申…

【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、取地址运算符重载 1. const修饰成员函数 2. 取地址运算符重载 二、深究构造函数 三、类型转换 四、static修饰成员 1. static修饰成员变…

监控系列之-prometheus部署说明

一、Prometheus介绍 Prometheus是一款开源的监控系统&#xff0c;主要用于收集、存储和查询时间序列数据&#xff0c;以便于对系统进行监控和分析Prometheus的架构由四个主要组件组成&#xff1a; 1、Prometheus Server &#xff1a;Prometheus Server是Prometheus的核心组件&a…

带你0到1之QT编程:十二、视图宝典,点通views的任督二脉

此为QT编程的第十二谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

text2sql(NL2Sql)综述《The Dawn of Natural Language to SQL: Are We Fully Ready?》

《The Dawn of Natural Language to SQL: Are We Fully Ready?》(github)出自2024年6月的NL2SQL(Natural language to SQL )综述论文。这篇论文尝试回答如下三个问题&#xff1a; 问题1:NL2SQL的现状是什么&#xff1f;(Q1:Where Are we Now?) 论文图1总结了近20年NL2SQL方法…

【移动端】菜单的自动展开与收回

前言 为了满足手机上菜单栏随用户移动&#xff0c;菜单的自动展示与隐藏&#xff0c;特此记录 基本原理 实现逻辑 window.addEventListener(‘scroll’, debouncedScrollHandler) – 监听文档视图滚动事件 document.querySelector(‘.header’) – 选择器匹配元素 创建show和h…

论文速递!Auto-CNN-LSTM!新的锂离子电池(LIB)剩余寿命预测方法

论文标题&#xff1a;A Data-Driven Auto-CNN-LSTM Prediction Model for Lithium-Ion Battery Remaining Useful Life 期刊信息&#xff1a;IEEE TII (中科院1区, JCR Q1, IF11.7) 引用&#xff1a;Ren L, Dong J, Wang X, et al. A data-driven auto-CNN-LSTM prediction m…

JavaScript web API part3

web API DOM 日期对象 > 得到当前系统的时间 new这个操作就是实例化 语法 const date new Date() or const date new Date(2004-11-3 08:00:00) 可以指定时间 > 可应用于通过系统时间和指定时间实现倒计时的操作 //得到当前时间const date new Date()console.lo…

多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测

多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测 目录 多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于BO-LSSVM贝叶斯优化最小二乘支…

Vue介绍、窗体内操作、窗体间操作学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

树莓派5上手

1 安装系统 Raspberry Pi OS 是基于 Debian 的免费操作系统&#xff0c;针对 Raspberry Pi 硬件进行了优化。Raspberry Pi OS 支持超过 35,000 个 Debian 软件包。树莓派 5 可以安装各种系统&#xff0c;但是如果对于系统没有特殊的要求&#xff0c;还是安装 Raspberry Pi OS …

【MySQL】MySQL索引与事务的透析——(超详解)

前言 &#x1f31f;&#x1f31f;本期讲解关于MySQL索引事务&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【MySQL】MySQL表的增删改查&#xff08;进阶篇&#xff09;——之查询操作&#xff08;超级详解&#xff09;-CSDN博客 &#x1f308;感…

CSP-CCF★★★201903-2二十四点★★★

目录 一、问题描述 二、解答 方法一&#xff1a;穷举法&#xff08;只列举了一部分&#xff09; 方法二&#xff1a;中缀表达式直接求值&#xff0c;两个栈&#xff0c;一个存放数值&#xff0c;一个存放符号 方法三&#xff1a;将中缀表达式转换为后缀来计算注意&#xff…