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

JS做贪吃蛇小游戏(源码)

一、HTML代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./../css/index.css">
</head>
<body><div class="container"><!-- 开始按钮 --><button class="start"></button><!-- 暂停按钮 --><button class="pause"></button></div><script src="../js/config.js"></script><script src="../js/index.js"></script>
</body>
</html>

二、css代码

html,body{margin: 0;padding:0 ;
}
/*容器样式*/
.container{width: 600px;height: 600px;background: #225675;border: 20px solid #7dd9ff;margin: 100px auto;position: relative;
}
/*按钮公共样式*/
button{border:none;outline: none;position: absolute;left: 50%;top: 50%;transform: translate(-50%,-50%);
}
/*开始按钮*/
.start{width: 200px;height: 200px;background: url(./../img/start.webp) center no-repeat;background-size: 100% 100%;display: block;
}
/*暂停按钮*/
.pause{width: 80px;height: 80px;background: url(./../img/b.webp) center no-repeat;background-size: 100% 100%;display: none;
}

三、JS代码

1.index.js

//绘制蛇的方法
function drawSnake(snake){for(var i=0;i<snake.snakePos.length;i++){if(!snake.snakePos[i].domConent){// 如果进入此if,说明是第一次创建蛇snake.snakePos[i].domConent=document.createElement("div");snake.snakePos[i].domConent.style.position="absolute";snake.snakePos[i].domConent.style.width=snakeBody+"px";snake.snakePos[i].domConent.style.height=snakeBody+"px";snake.snakePos[i].domConent.style.left=snake.snakePos[i].x*snakeBody+"px";snake.snakePos[i].domConent.style.top=snake.snakePos[i].y*snakeBody+"px";if(snake.snakePos[i].flag==='head'){//进入此if说明是蛇头snake.snakePos[i].domConent.style.background=`url("../img/a.webp") center/contain no-repeat`;//根据方向进行旋转switch(snake.direction.flag){case "top":{snake.snakePos[i].domConent.style.transform=`rotate(-90deg)`;break;}case "bottom":{snake.snakePos[i].domConent.style.transform=`rotate(90deg)`;break;}case "left":{snake.snakePos[i].domConent.style.transform=`rotate(180deg)`;break;}case "right":{snake.snakePos[i].domConent.style.transform=`rotate(0deg)`;break;}}}else{//说明是蛇身snake.snakePos[i].domConent.style.background="#e69009";snake.snakePos[i].domConent.style.borderRadius="50%"}}//需要将创建的DOM 元素添加到容器当中document.querySelector(".container").append(snake.snakePos[i].domConent)}
}//绘制食物的方法
function drawFood(){//1.食物是随机的//2.食物不能再蛇头或蛇身的位置while(true){//构成一个死循环,直到生成符合要求的食物坐标才能退出var isRepeat=false//默认生成的坐标是符合要求的//随机生成一个坐标food.x=Math.floor(Math.random()*tr+0)food.y=Math.floor(Math.random()*tr+0)//查看是否符合要求for(var i=0;i<snake.snakePos.length;i++){if(snake.snakePos[i].x===food.x&&snake.snakePos[i].y===food.y){//当前生成的食物,和蛇的坐标冲突了isRepeat = true;break; //跳出for循环}}if(!isRepeat){break;//跳出while循环}}//整个while循环跳出来以后u,食物的坐标一定是ok的if(!food.domConent){food.domConent = document.createElement("div")food.domConent.style.width = snakeBody+"px";food.domConent.style.height = snakeBody+"px";food.domConent.style.position = "absolute";food.domConent.style.background=`url("../img/apple.webp") center/contain no-repeat`;document.querySelector(".container").append(food.domConent);}food.domConent.style.left = food.x * snakeBody + "px";food.domConent.style.top = food.y * snakeBody + "px";
}// 初始化游戏
function initGame(){// 1.初始化地图for(var i=0;i<tr;i++){for(var j=0;j<td;j++){gridData.push({x:j,y:i})}}// console.log(gridData) //2.绘制蛇drawSnake(snake);//3.绘制食物 drawFood()
}
// 碰撞检测
function isCollide(newHead){var collideCheckInfo={isCollide:false,  //是否碰撞墙壁蛇身isEat:false       //是否迟到食物}// 是否碰到墙壁if(newHead.x<0||newHead.x>=td||newHead.y<0||newHead.y>=tr){collideCheckInfo.isCollide =true;return collideCheckInfo;}//检测是否碰到自己for(var i=0 ; i<snake.snakePos.length;i++){if(snake.snakePos[i].x === newHead.x && snake.snakePos[i].y===newHead.y){collideCheckInfo.isCollide=true;return collideCheckInfo;}}// 检测是否吃到东西if(newHead.x === food.x&&newHead.y===food.y){collideCheckInfo.isEat =true;score++;  //分数自增}return collideCheckInfo;
}// 蛇的移动
function snakeMove(){var oldHead =snake.snakePos[snake.snakePos.length-1]//根据方向计算出新的蛇头坐标var newHead ={domConent:"",x : oldHead.x + snake.direction.x,y : oldHead.y + snake.direction.y,flag:"head",}// 首先先进行碰撞检测,看计算出来的新的蛇头有没有碰上食物,蛇身体,墙壁var collideCheckResult= isCollide(newHead);if(collideCheckResult.isCollide){//说明碰墙le// console.log("碰墙")if(window.confirm(`游戏结束,您当前的得分为${score}分,是否要重新开始游戏`)){//重新开始游戏// console.log("重新开始游戏")document.querySelector(".container").innerHTML=`<!-- 开始按钮 --><button class="start" style="display:none"></button><!-- 暂停按钮 --><button class="pause" style="display:none"></button>`;score =0;snake ={//设一开始移动的方向direction:directionNumber.right,//蛇的初始位置snakePos:[{x:0,y:0,domConent:"",flag:"body"},{x:1,y:0,domConent:"",flag:"body"},{x:2,y:0,domConent:"",flag:"body"},{x:3,y:0,domConent:"",flag:"head"}]};food = {x:0 , y:0  ,domConent:""};initGame();}else{//结束游戏document.onkeydown = null;clearInterval(timerStop)// console.log("取消游戏")}return;}//将旧的头修改为身体oldHead.flag = "body";oldHead.domConent.style.background ="#e69009";oldHead.domConent.style.borderRadius ="50%";snake.snakePos.push(newHead);// 判段是否吃到东西if(collideCheckResult.isEat){//重新生成新的食物drawFood();}else{//没有吃到,移除最后一个document.querySelector(".container").removeChild(snake.snakePos[0].domConent)snake.snakePos.shift();}// 重新绘制蛇drawSnake(snake);
}//
function startGame(){timerStop = setInterval(function(){snakeMove()},time)
}// 绑定事件
function bindEvent(){// 首先是键盘事件,用户按上下左右,蛇可以移动document.onkeydown = function(e){// console.log(e.key)if((e.key === "ArrowUp" || e.key.toLocaleLowerCase() === "w")&&snake.direction.flag !== "bottom"){//用户按下上建snake.direction=directionNumber.top;event.preventDefault(); // 阻止方向键默认行为(如页面滚动)}if((e.key === "ArrowDown" || e.key.toLocaleLowerCase() === "s")&&snake.direction.flag !=="top"){//用户按下下建snake.direction=directionNumber.bottom;event.preventDefault(); // 阻止方向键默认行为(如页面滚动)}if((e.key === "ArrowLeft" || e.key.toLocaleLowerCase() === "a")&&snake.direction.flag !== "right"){//用户按下左建snake.direction=directionNumber.left;event.preventDefault(); // 阻止方向键默认行为(如页面滚动)}if((e.key === "ArrowRight" || e.key.toLocaleLowerCase() === "d")&&snake.direction.flag !== "lefts"){//用户按下右建snake.direction=directionNumber.right;event.preventDefault(); // 阻止方向键默认行为(如页面滚动)}// snakeMove();}//2.计时器自动调用蛇移动的方法startGame();//3.点击整个容器的时候可以暂停和重新开始游戏document.querySelector(".container").onclick = function(e){//这里是通过事件委托的形式,判断用户究竟点击的时候container容器还是暂停按钮,从而做出不同的操作if(e.target.className === "container"){//做暂停操作document.querySelector(".pause").style.display = 'block';clearInterval(timerStop);}else{//恢复游戏操作document.querySelector(".pause").style.display = 'none';startGame();}	}
}
// 主方法
function main(){//用户点击了开始游戏之后,再做后续的工作document.querySelector(".start").onclick= function(e){e.stopPropagation();document.querySelector(".start").style.display="none"//1.初始化游戏initGame();// 2.绑定事件bindEvent();}}
main();

2.config.js(游戏相关设置)

// 游戏相关的配置var gridData = [];//存储地图对象
// 整个网格的行与列
var tr = 30;
var td = 30;//蛇的身体大小
var snakeBody = 20;// 新的蛇头和旧的蛇头之间的关系
var directionNumber={// 我们在确定新的蛇头的时候,会拿下面的对象和旧蛇头做一个计算,从而得出新蛇头的位置left:{x:-1,y:0,flag:"left"},right:{x:1,y:0,flag:"right"},top:{x:0,y:-1,flag:"top"},bottom:{x:0,y:1,flag:"bottom"}
}//蛇相关的配置信息
var snake ={//设一开始移动的方向direction:directionNumber.right,//蛇的初始位置snakePos:[{x:0,y:0,domConent:"",flag:"body"},{x:1,y:0,domConent:"",flag:"body"},{x:2,y:0,domConent:"",flag:"body"},{x:3,y:0,domConent:"",flag:"head"}]
}
//食物的相关配置信息
var food = {x:0 , y:0  ,domConent:""
}
//游戏分数
var  score= 0
//停止计时器
var timerStop = null
//计时器事件
var time=100

相关文章:

JS做贪吃蛇小游戏(源码)

一、HTML代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><link rel…...

烽火HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包及注意点说明

之前发布过这个固件包&#xff0c;关于烽火HG680-KA&#xff0f;HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包详细说明一下&#xff0c;汇总总结一些常遇到的情况&#xff0c;这次固件会分开发布&#xff0c;以免混淆。 上一个帖子地址&#xff1a;烽火HG680-KA&#xff0…...

Java数据结构相关知识

文章目录 1. 自动装箱和自动拆箱2. Object的equals方法3. Comparable和Comparator接口 1. 自动装箱和自动拆箱 自动装箱&#xff1a;将基本数据类型自动转换为对应的包装类。自动拆箱&#xff1a;将包装类自动转换为对应的基本数据类型。 显示装箱 int primitiveInt 10; //…...

996引擎 - 红点系统

996引擎 - 红点系统 总结NPC 红点(TXT红点)Lua 红点1. Red_Point.lua2. UI_Ex.lua参考资料以下内容是在三端 lua 环境下测试的 总结 红点系统分几个部分组成。 M2中设置变量推送。 配置红点表。 Envir\Data\cfg_redpoint.xls 2.1. UI元素中找到ID填写 ids 列。 主界面挂载…...

7种数据结构

7种数据结构 顺序表sqlite.hseqlite.c 单链表linklist.clinklist.h 双链表doulinklist.cdoulinklist.h 链式栈linkstack.clinkstack.h 队列SeqQueue.cSeqQueue.h 树tree.c 哈希表hash.c 顺序表 sqlite.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ typedef struct person…...

Redis的消息队列是怎么实现的

Redis 本身并不是一个专门的消息队列系统,但它的 List、Pub/Sub 和 Stream 数据结构可以用来实现消息队列的功能。以下是 Redis 实现消息队列的几种常见方式: 1. 基于 List 实现消息队列 Redis 的 List 是一个双向链表,支持在头部和尾部进行高效的插入和删除操作,非常适合…...

3.17BUUCTF练习day1

BUUCTF练习day1 [极客大挑战 2019]EasySQL1&#xff08;字符型&#xff0c;账号密码型&#xff0c;get型&#xff09; 判断闭合方式 在用户名输入1‘&#xff0c;此时密码先输入任何数字时&#xff0c;出现语法错误 说明闭合方式为单引号闭合&#xff0c;在判断完闭合方式后…...

【贪心算法】柠檬水找零

1.题目解析 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 2.讲解算法原理 分情况讨论 5---》直接收下 10---》找五元&#xff0c;收下 20----》105△ ----》555 由于5元更有用&#xff0c;则尽可能保留5元 3.代码 class Solution {public boolean lemonadeCh…...

黑马跟学.苍穹外卖.Day08

黑马跟学.苍穹外卖.Day08 苍穹外卖-day8课程内容1. 工作台1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计 1.2 代码导入1.2.1 Controller层1.2.2 Service层接口1.2.3 Service层实现类1.2.4 Mapper层 1.3 功能测试1.3.1 接口文档测试1.3.2 前后端联调测试 1.4 代码提交 2. Ap…...

ABAP语言的动态编程(4) - 综合案例:管理费用明细表

本篇来实现一个综合案例&#xff1a;管理费用明细表。报表在实际项目中&#xff0c;也有一定的参考意义&#xff0c;一方面展示类似的报表&#xff0c;比如管理费用、研发费用等费用的明细&#xff0c;使用业务比较习惯的展示格式&#xff1b;另一方面正好综合运用前面学习的动…...

通过Geopandas进行地理空间数据可视化

目录 引言 安装与导入 数据加载与探索 数据预处理 基本地图可视化 添加其他数据到地图上 空间分析与查询 地图叠加与分组 空间缓冲区 交互式地图可视化 实际应用案例 城市规划 环境监测 结论 引言 在数据科学领域,地理空间数据可视化扮演着至关重要的角色。它不…...

【大语言模型_5】xinference部署embedding模型和rerank模型

一、安装xinference pip install xinference 二、启动xinference ./xinference-local --host0.0.0.0 --port5544 三、注册本地模型 1、注册embedding模型 curl -X POST "http://localhost:5544/v1/models" \ -H "Content-Type: application/json" \…...

CSS3学习教程,从入门到精通,CSS3 选择器权重问题语法知识点及案例代码(5)

CSS3 选择器权重问题语法知识点及案例代码 一、选择器权重概述 在 CSS 中&#xff0c;当多个选择器同时匹配同一个元素时&#xff0c;浏览器会根据选择器的权重来决定哪个样式生效。权重高的选择器的样式会覆盖权重低的选择器的样式。 二、选择器权重计算规则 1. 内联样式&…...

在Vue3中使用Echarts的示例

1.常用-引用ts文件方式 1.1 导出ts文件-一个简单的柱状图 export const baseBarChart (xdata: string[], data: number[][], legendData: string[]) > {if (data.length 0) {return noData;}// 定义颜色数组const color [#00CCCC,#FF9900,#1677DC,#FF6666,#B366FF,#666…...

Three.js 阴影 (Shadow) 知识点整理

阴影主要由 castShadow 和 receiveShadow 控制&#xff0c;并通过不同类型的光源 (DirectionalLight、SpotLight、PointLight) 生成。我们将系统地整理与阴影相关的知识点。 1️⃣ 基础概念 castShadow &#x1f3ad;&#xff1a;物体是否投射阴影。receiveShadow &#x1f3d…...

GHCTF web方向题解

upload?SSTI! import os import refrom flask import Flask, request, jsonify,render_template_string,send_from_directory, abort,redirect from werkzeug.utils import secure_filename import os from werkzeug.utils import secure_filenameapp Flask(__name__)# 配置…...

Logic-RL:小参数qwen模型复现DeepSeek R1 zero

最近很多参照DeepSeek模型训练推理模型的工作,本文将深入 “Logic-RL: Unleashing LLM Reasoning with Rule-Based Reinforcement Learning” 的论文,该论文提出了一种Rule-Based Reinforcement Learning, Logic-RL框架,旨在提升 LLM 的逻辑推理能力,在qwen2.5-7b-instruct…...

CVE-2017-5645(使用 docker 搭建)

介绍: 是一个与 Apache Log4j2 相关的安全漏洞,属于远程代码执行,它可能允许攻击者通过构造恶意的日志信息 在目标系统上执行任意代码 Log4j2 介绍 Log4j2 是 Apache 的一个日志记录工具,属于 Java 应用的日志框架,它是 Log4j 的升级版,性能更好,功能更多.它被广泛的适用于 J…...

conda install 和 pip install 的区别

conda install 和 pip install 是两个常用的包安装命令&#xff0c;但它们在很多方面存在差异。 1. 所属管理系统不同 1.1 conda install conda install 是Anaconda和Miniconda发行版自带的包管理工具 conda 的安装命令。conda 是一个跨平台的开源包管理系统和环境管理系统&…...

蓝桥杯备考:特殊01背包问题——》集合subset

我们划分成两个集合&#xff0c;实际上我们只需要看一部分就行了&#xff0c;也就是从集合的所有元素里挑出恰好满足集合总和的一半儿&#xff0c;当然&#xff0c;如果我们的集合总和是奇数的话&#xff0c;我们是无论如何也挑不出刚好一半儿的&#xff0c;因为我们没有小数&a…...

设计模式之外观模式:原理、实现与应用

引言 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过提供一个统一的接口来简化复杂系统的使用。外观模式隐藏了系统的复杂性&#xff0c;使得客户端可以通过一个简单的接口与系统交互。本文将深入探讨外观模式的原理、实现方式以及实…...

C#设计模式Demo——MVC

设计模式Demo——MVC 1.View1.1页面示例1.2View代码1.3修改界面以及代码 2.Model3.Controller4.数据结构5.枚举类型6.工具类6.1缓存信息6.2扩展类. 文件结构图 1.View 1.1页面示例 1.2View代码 using System; using System.Data; using System.Windows.Forms; using MVC模式…...

【sql靶场】第18-22关-htpp头部注入保姆级教程

目录 【sql靶场】第18-22关-htpp头部注入保姆级教程 1.回顾知识 1.http头部 2.报错注入 2.第十八关 1.尝试 2.爆出数据库名 3.爆出表名 4.爆出字段 5.爆出账号密码 3.第十九关 4.第二十关 5.第二十一关 6.第二十二关 【sql靶场】第18-22关-htpp头部注入保姆级教程…...

LabVIEW棉花穴播器排种自动监测系统

一、项目背景与行业痛点 1. 农业需求驱动 我国棉花主产区&#xff0c;种植面积常年超250万公顷&#xff0c;传统人工播种存在两大核心问题&#xff1a; 效率瓶颈&#xff1a;人均日播种面积不足0.5公顷&#xff0c;难以匹配规模化种植需求&#xff1b; 精度缺陷&#xff1a;人…...

【程序人生】成功人生架构图(分层模型)

文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层&#xff1a;调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…...

golang开发支持onlyoffice的token功能

一直都没去弄token这块&#xff0c;想着反正docker run的时候将jwt置为false即可。 看了好多文章&#xff0c;感觉可以试试&#xff0c;但是所有文件几乎都没说思路。 根据我的理解和成功的调试&#xff0c;思路是&#xff1a; 我们先定义2个概念&#xff0c;一个是文档下载…...

Qt for WebAssembly程序中文乱码问题处理过程

一、环境 操作系统DeepinV23 Qt版本6.8.2 编程语言C 二、问题现象 Qt for WebAssembly应用在浏览器页面上英文字母显示正常&#xff0c;中文显示为乱码。 经测试分析原因为默认字体不能正常显示汉字。 三、处理过程 1.准备中文字体文件 从Windows下复制宋体简体字体文件…...

速通大厂测开

最近26届暑期实习招聘和25届春招已经开始&#xff0c;测开学习圈也有同学拿到offer了 今天分享一位25届秋招圈友快速拿到大厂测开offer的经历&#xff0c;希望对大家有所帮助 我是某211本科生&#xff0c;在去年暑假准备考研的间隙意外收获了某大厂测开实习offer&#xff0c;…...

基于Netty实现高性能HTTP反向代理

以下将分步骤实现一个基于Netty的高性能HTTP反向代理&#xff0c;支持动态路由、负载均衡和基础鉴权功能。 1. 项目依赖配置&#xff08;Maven&#xff09; 2. 定义路由规则 3. 实现HTTP反向代理服务端 4. 实现反向代理处理器 5. 实现基础鉴权 6. 性能优化策略 连接池管理…...

Spring Boot集成MyBatis与MySQL

Spring Boot集成MyBatis与MySQL开发全攻略 一、前言&#xff1a;现代Java持久层开发的选择 在微服务架构盛行的今天&#xff0c;Spring Boot以其"约定优于配置"的理念成为Java开发的事实标准。结合MyBatis这一灵活高效的ORM框架和MySQL这一成熟稳定的关系型数据库&…...