自制HTML5游戏《贪吃蛇》

news2024/11/24 17:53:50

一、游戏简介

        贪吃蛇是一款经典的电子游戏,最早在1976年由Gremlin公司推出,名为"Blockade"。游戏的玩法简单却富有挑战性,玩家控制一条蛇在封闭的场地内移动,通过吃食物增长身体,同时避免撞到自己的身体或场地边界。随着时间的推移,贪吃蛇游戏经历了多次演变,但其核心玩法依然受到玩家的喜爱。

二、为什么选择贪吃蛇游戏

  1. 经典性:贪吃蛇是一款历史悠久的游戏,其经典性使得它成为学习编程和游戏开发的理想选择。

  2. 简单性:游戏规则简单,易于理解,适合初学者作为编程练习项目。

  3. 互动性:贪吃蛇游戏具有高度的互动性,玩家需要快速反应和策略思考。

  4. 可扩展性:基础游戏可以扩展多种功能,如增加难度级别、特殊道具等,为学习者提供更多实践机会。

三、游戏目标

        贪吃蛇游戏的主要目标是控制蛇头吃到随机出现在游戏场地的苹果,每吃到一个苹果,蛇的身体就会增长一段。玩家需要避免蛇头撞到自己的身体或游戏场地的边界。游戏的难度会随着蛇身的增长而增加,玩家的目标是尽可能获得更高的分数。

四、游戏界面设计

游戏界面通常由以下几个部分组成:

  1. 游戏画布:一个矩形区域,作为蛇移动和吃苹果的场所。

  2. :由多个小方块组成,每个方块代表蛇的身体部分,蛇头通常有特殊的标识。

  3. 苹果:一个单独的方块,随机出现在游戏画布上,作为蛇的食物。

  4. 得分板:显示玩家当前的得分和游戏等级。

五、游戏逻辑概述

游戏逻辑主要包括以下几个方面:

  1. 初始化:设置游戏初始状态,包括蛇的位置、长度和方向,苹果的位置,以及得分和等级。

  2. 键盘控制:监听键盘按键,根据玩家的输入改变蛇的移动方向。

  3. 移动逻辑:更新蛇的位置,使其按照指定方向移动。

  4. 碰撞检测:检查蛇头是否撞到自己、边界或苹果。

  5. 吃苹果:如果蛇头碰到苹果,更新苹果的位置,增长蛇的身体,并增加得分。

  6. 游戏结束:如果蛇撞到自己或边界,显示游戏结束的提示,并结束游戏循环。

  7. 得分和等级:根据吃到的苹果数量增加得分,并根据得分调整游戏难度。

六、创建基本的HTML5文档结构

        在创建贪吃蛇游戏之前,首先需要构建一个基本的HTML5文档结构。这个结构包括了文档的头部(head)和主体(body),其中头部用于引入CSS样式和JavaScript脚本,而主体则包含了游戏的所有元素。

源代码示例 - HTML5文档结构
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇游戏</title>
    <link rel="stylesheet" href="styles/base.css">
    <link rel="stylesheet" href="styles/snake.css">
</head>
<body>
    <!-- 游戏画布和元素将在此处添加 -->
    <script src="scripts/snake.js"></script>
</body>
</html>
设定游戏画布 (<div id="box">)

游戏画布是一个<div>元素,它作为游戏的容器,包含了蛇、苹果和得分板。这个<div>具有固定的宽度和高度,并且使用CSS样式来设置其位置和外观。

源代码示例 - HTML中的游戏画布
<div id="box">
    <!-- 蛇的身体由列表项组成,苹果是一个div,得分板将在JavaScript中动态添加 -->
    <ul id="snake"></ul>
    <div id="apple"></div>
</div>
<div id="score">得分: <span id="score-value">0</span> 等级: <span id="level-value">1</span></div>
添加游戏元素(蛇头、蛇身、苹果、得分板)
  1. 蛇头:通常用一个带有图片的<li>元素表示,这个<li><ul id="snake">的第一个子元素。

  2. 蛇身:由多个<li>元素组成,这些元素将通过JavaScript动态添加到蛇的列表中。

  3. 苹果:用一个<div id="apple">表示,它的位置将通过JavaScript动态设置。

  4. 得分板:一个包含得分和等级的<div>元素,位于游戏画布之外。

源代码示例 - JavaScript中添加蛇头和蛇身
window.onload = function() {
    var snakeList = document.getElementById('snake');
    var snakeHead = document.createElement('li');
    snakeHead.innerHTML = '<img src="head.png" alt="蛇头">'; // 假设有一个蛇头图片
    snakeList.appendChild(snakeHead);
​
    // 初始蛇身长度,例如5个单位
    for (var i = 0; i < 5; i++) {
        var snakeBodyPart = document.createElement('li');
        snakeList.appendChild(snakeBodyPart);
    }
​
    var apple = document.getElementById('apple');
    // 设置苹果的初始位置
    apple.style.left = '100px';
    apple.style.top = '100px';
};

七、效果图

        

八、完整代码

        HTML

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="base.css" />
    <link rel="stylesheet" href="snake.css" />
    <script src="snake.js"></script>
</head>

<body>
    <div id="score">
        得分: <span>0</span>
        等级: <span>1</span>
    </div>
    <div id="box">
        <ul id="snake">
            <li class="heihei" id="head"><img src="right.png" alt="" /></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
            <li class="heihei"></li>
        </ul>
        <div id="apple"></div>
    </div>
    <script>
    </script>
</body>

</html>

        snake.css

#box{
    width: 800px;
    height: 600px;
    position: relative;
    background-color: #d5e3bd;
    border: 1px solid #000;
    margin: 30px auto;
}
#snake{
    /*position: absolute;*/
    /*top: 200px;*/
    /*left: 350px;*/
}
.heihei{
    width: 20px;
    height: 20px;
    /*border: 1px solid #000;*/
    border-radius: 10px;
    background-color: rgb(13, 113, 85);
    position: absolute;
    text-align: center;
    line-height: 20px;
    position: absolute;
    top: 200px;
    left: 350px;
    color: white;
}
#head img{
    width: 20px;
}
#apple{
    width: 20px;
    height: 20px;
    background-color: darkred;
    position: absolute;
    top: 140px;
    left: 400px;
}
#score{
    width: 100px;
    height: 100px;
    border: 1px solid #000;
    position: absolute;
    text-align: center;
    line-height: 100px;
    left: 1100px;
    z-index: 1;
}

        base.css

@charset "UTF-8";
/*css 初始化 */
html, body, ul, li, ol, dl, dd, dt, p, h1, h2, h3, h4, h5, h6, form, fieldset, legend, img {
    margin: 0;
    padding: 0;
}

/*各浏览器显示不同,去掉蓝色边框*/
fieldset, img, input, button {
    border: none;
    padding: 0;
    margin: 0;
    outline-style: none;
}

ul, ol {
    list-style: none;
}

/*统一组合框的默认样式*/
input {
    padding-top: 0;
    padding-bottom: 0;
    font-family: "sums-song", "宋体";
}

select, input, button {
    vertical-align: middle;
}

select, input, textarea {
    font-size: 12px;
    margin: 0;
}

/*防止拖动 影响布局*/
textarea {
    resize: none;
}

/*去掉行内替换元素空白缝隙*/
img {
    border: 0;
    vertical-align: middle;
}

table {
    border-collapse: collapse;
}

body {
    font: 12px/150% Arial, Verdana, "\5b8b\4f53"; /*宋体 unicode */
    color: #666;
    background: #fff;
}

/*清除浮动*/
.clearfix:before, .clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1; /*IE/7/6*/
}

a {
    color: #666;
    text-decoration: none;
}

a:hover {
    color: #C81623;
}

h1, h2, h3, h4, h5, h6 {
    text-decoration: none;
    font-weight: normal;
    font-size: 100%;
}

s, i, em {
    font-style: normal;
    text-decoration: none;
}

/*京东色*/
.col-red {
    color: #C81623 !important;
}

/*公共类*/
.w {
    /*版心 提取 */
    width: 1210px;
    margin: 0 auto;
}

.fl {
    float: left;
}

.fr {
    float: right;
}

.al {
    text-align: left;
}

.ac {
    text-align: center;
}

.ar {
    text-align: right;
}

.hide {
    display: none;
}

        js代码

window.onload = function() {
    var ul = document.getElementById("snake");
    var lis = ul.children;
    var head = lis[0];
    var img = head.getElementsByTagName("img")[0];
    var box = document.getElementById("box");
    var apple = document.getElementById("apple");
    var score = document.getElementById("score").getElementsByTagName("span")[0];
    var level = document.getElementById("score").getElementsByTagName("span")[1];
    var gameOver;
    var square = 20;
    var dirArr = {
        left: { name: "left", key: 65, point: { x: -1, y: 0 }, img: "left.png" },
        right: { name: "right", key: 68, point: { x: 1, y: 0 }, img: "right.png" },
        up: { name: "up", key: 87, point: { x: 0, y: -1 }, img: "up.png" },
        down: { name: "down", key: 83, point: { x: 0, y: 1 }, img: "down.png" }
    };
    var dirList = [];
    var currentDir = dirArr["right"];
    document.onkeydown = function(event) {
        var event = event || window.event;
        addDirection(event.keyCode);
    }

    function addDirection(key) {
        var dir;
        // 获取方向
        for (k in dirArr) {
            if (dirArr[k].key == key) {
                dir = dirArr[k];
            }
        }
        if (!dir) {
            return;
        }
        //获取上一次的方向
        var lastDirection = dirList[dirList.length - 1];
        if (!lastDirection) { lastDirection = currentDir }
        if (lastDirection.name == dir.name) {
            return;
        } else if (lastDirection.point.x + dir.point.x == 0 && lastDirection.point.y + dir.point.y == 0) {
            return;
        }
        if (dirList.length > 3) {
            return;
        }
        dirList.push(dir);
    }

    function getDirection(arr) {
        if (arr.length != 0) {
            currentDir = arr.shift();
        }
        return currentDir;
    }

    function point(x, y) {
        this.x = x;
        this.y = y;
    }

    function move() {
        //处理按键队列
        var d = getDirection(dirList);
        img.src = d.img;
        //下一个要走的点
        var pre = new point(head.offsetLeft + d.point.x * square, head.offsetTop + d.point.y * square);
        //死亡判定机制
        if (die(pre)) {
            clearInterval(timer)
            alert("GAME_OVER");
            return;
        }
        //吃的机制
        if (eat(pre)) {
            console.log("eat");
        }
        //移动身子
        for (var i = lis.length - 1; i > 0; i--) {
            lis[i].style.left = lis[i - 1].offsetLeft + "px";
            lis[i].style.top = lis[i - 1].offsetTop + "px";
        }
        head.style.left = pre.x + "px";
        head.style.top = pre.y + "px";
    }
    var timer = setInterval(move, 300);

    function die(p) {
        var left = p.x;
        var right = p.x + head.offsetWidth;
        var toper = p.y;
        var bottom = p.y + head.offsetHeight;
        for (var i = 1; i < lis.length - 1; i++) {
            if (left == lis[i].offsetLeft && toper == lis[i].offsetTop)
                return 1;
        }
        if (left < 0 || toper < 0 || right > box.offsetWidth || bottom > box.offsetHeight) {
            console.log(1)
            return 1;
        }
    }
    //初始化
    for (var i = 0; i < lis.length; i++) {
        lis[i].idx = i;
        lis[i].style.left = -square * i + "px";
        var backgroundColor = parseInt(255 * 255 * 255 * Math.random());
        lis[i].style.backgroundColor = "#" + backgroundColor.toString(16);
    }

    //吃
    function eat(p) {
        if (p.x == apple.offsetLeft && p.y == apple.offsetTop) {
            apple.style.left = 20 * Math.floor(Math.random() * 39) + "px";
            apple.style.top = 20 * Math.floor(Math.random() * 29) + "px";
            var li = document.createElement("li");
            li.className = "heihei";
            var backgroundColor = parseInt(255 * 255 * 255 * Math.random());
            li.style.backgroundColor = "#" + backgroundColor.toString(16);
            ul.appendChild(li);
            score.innerHTML++;
            clearInterval(timer);
            var scoreLevel = Math.floor(score.innerHTML / 4);
            level.innerHTML = scoreLevel + 1;
            var timeLevel = scoreLevel > 7 ? 7 : scoreLevel;
            timer = setInterval(move, 250 - timeLevel * 25);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1852875.html

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

相关文章

webpack处理html资源11--webpack入门学习

处理 Html 资源 1. 下载包 npm i html-webpack-plugin -D 2. 配置 webpack.config.js const path require("path"); const ESLintWebpackPlugin require("eslint-webpack-plugin"); const HtmlWebpackPlugin require("html-webpack-plugin"…

图解注意力

图解注意力 Part #2: The Illustrated Self-Attention 在文章前面的部分&#xff0c;我们展示了这张图片来展示自注意力被应用于正在处理单词"it"的一层中&#xff1a; 在本节中&#xff0c;我们将看看这是如何完成的。请注意&#xff0c;我们将以一种试图理解单…

JAVA期末复习2

目录 一、Java基础知识 1. 下面几个标识符中&#xff0c;哪些是命名正确的 (A) 2. 分析以下代码&#xff0c;哪些是合法的 (C) 3. 以下代码的执行结果是&#xff08; B &#xff09; 4. 下面哪个不是java中的关键字&#xff1f;&#xff08; B &#xff09; 5. 下面对数组…

编译原理期末复习

BUCT往年试题为导向的复习 标*的为往年真题 目录 1.基本概念 *例题&#xff08;编译主要阶段&#xff09; 编译程序与解释性程序区别 LL(1)概念 2.正则表达式转DFA (1)正则表达式转NFA 第一种方法(编程时常用) 第二种&#xff08;考试时常用&#xff09; &#xff08…

19 Shell编程之条件语句

目录 19.1 条件测试操作 19.1.1 文件测试 19.1.1 整数值比较 19.1.3 字符串比较 19.1.4 逻辑测试 19.2 if条件语句 19.2.1 if语句的结构 19.2.2 if语句应用示例 19.3 case分支语句 19.3.1 case语句的结构 19.3.2 case语句应用示例 19.1 条件测试操作 Shell环境根据命令执行后…

Agile Software Development

Individuals and interactions over processes and tools.(个人和协作超过过程和工具) working software over comprehensive documentation.(工作软件超过完全文档) Customer collaboration over contract negotiation.(客户协作超过合同谈判) Responding to change over f…

数据结构与算法笔记:基础篇 - 初始动态规划:如何巧妙解决“双十一”购物时的凑单问题?

概述 淘宝的 “双十一” 购物节有各种促销活动&#xff0c;比如 “满 200 元减 50元”。假设你女朋友购物车中有 n 个&#xff08;n > 100&#xff09;想买的商品&#xff0c;它希望从里面选几个&#xff0c;在凑够满减条件的前提下&#xff0c;让选出来的商品价格总和最长…

urfread刷算法题day4|27. 移除元素+复习

27. 移除元素 题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。 元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以…

maven的安装以及配置

前言&#xff1a; Maven是一个强大的构建自动化工具&#xff0c;主要用于Java项目。它解决了软件开发中的两个方面&#xff1a; 构建和依赖管理&#xff1a;Maven通过在项目对象模型&#xff08;POM&#xff09;文件中指定依赖关系&#xff0c;简化了项目构建和依赖管理的过程…

Vendors and Customers(酒吧餐厅厨师人物动画动作)

此包包含商店、酒吧和餐馆中顾客和工作人员的各种动画。 包括: 饮食动画。站立、倾斜和坐着(酒吧凳子和椅子),以及各种姿势的进入和退出动画,坐姿变化(腿抬起、弯腰、交叉腿、向后倾斜)和害怕反应动画(举手、躲藏、畏缩)。 厨师烹饪动画(煎锅、炒锅、平底锅、锅)、食…

《Python 机器学习》作者新作:从头开始构建大型语言模型,代码已开源

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 自 ChatGPT 发布以来&#xff0c;大型语言模型&#xff08;LLM&#xff09;已经成为推动人工智能发展的关键技术。 近期&#xff0c;机器学习和 AI 研究员、畅销书《Python 机器学习》作者 Sebastian …

CMMM Plus+ Calculus Update 超级游戏大作 游戏说明

资源链接 关卡编辑器 ◽️使用 WASD 移动视图。 ◽️LMB 放置单元格。 ◽️Space LMB 删除单元格。Ctrl Space LMB 删除所有相同类型的单元格。 ◽️Q / E 旋转单元格。 ◽️Z / X 在单元格类别之间切换。 ◽️键 1-9 快速选择单元格。 ◽️按 F 显示可拖动的图块。 ⌨️控…

【SpringCloud】OpenFeign-远程调用

本文基于上一篇http://t.csdnimg.cn/0qm2R 的基础上添加OpenFeign的使用。 微服务通信 在微服务架构中&#xff0c;微服务之间的通信通常有两种方式&#xff1a;RPC 和 HTTP。在 Spring Cloud 中&#xff0c;默认使用 HTTP 进行微服务的通信&#xff0c;最常用的实现形式有两…

idea或vscode支持vue语法,ts可解析*.vue

一、ide不能解析vue文件 刚开始导入时&#xff0c;在vscode中的vue文件中内容都是灰色的 ide不能解析vue解决方法&#xff1a; 1.idea或webstorm安装vue.js插件 2.在vscode中 vue2.0的项目安装vetur插件vue3.0及以上的项目安装Vue-official插件&#xff08;之前是Volar&…

WordPress项目教程:自动采集并发布,让你轻松实现网站内容更新

随着互联网的发展&#xff0c;越来越多的人开始关注自己的个人网站&#xff0c;通过网站展示自己的才华、分享知识、推广产品等。然而&#xff0c;个人网站的运营并非易事&#xff0c;尤其是内容更新方面。为了解决这个问题&#xff0c;今天我们将为大家推荐一款WordPress插件主…

使用C语言实现植物大战僵尸教程

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

数据资产与云计算深度融合:借助云计算技术,优化数据存储、高效处理并创新应用,驱动企业数字化转型

目录 一、引言 二、数据资产与云计算深度融合的必要性 1、数据资产的重要性 2、云计算技术的优势 三、云计算技术在数据资产管理中的应用 1、数据存储的优化 2、数据处理的高效性 3、数据应用的创新 四、云计算驱动企业数字化转型的实践案例 案例一&#xff1a;金融行…

STM32玩转物联网07-WIFI实验

前言 上一节我们学习了串口的简单使用&#xff0c;本节我们增加难度&#xff0c;做一个demo通过AT指令控制ESP8266&#xff0c;使用DMA方式接收ESP8266发来的数据&#xff0c;后续我们便开始通过ESP8266连接物联网云平台&#xff0c;敬请关注。 一、准备 1. ESP8266硬件准备 准…

[图解]建模相关的基础知识-16

1 00:00:00,350 --> 00:00:04,130 刚才那个&#xff0c;就相当于&#xff0c;12这个我们可以认为是什么 2 00:00:05,020 --> 00:00:11,360 我们用类图来表达就是&#xff0c;员工、电话 3 00:00:13,320 --> 00:00:15,080 多个 4 00:00:15,090 --> 00:00:16,440 …

stm32使用time模块输出pwm波,stm32-matlab开发电机控制

simulink: stm32cubemx : 注意在stm32配置了两路的一个互补输出&#xff0c;但实际上在matlab里只需要给定占空比就行了&#xff0c;他会自动输出互补&#xff0c;驱动电机&#xff0c;这是因为有点的电机输出需要6路&#xff0c;有的只需要1路&#xff0c;我们看下图就知道了…