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盘强刷固件包及注意点说明
之前发布过这个固件包,关于烽火HG680-KA/HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包详细说明一下,汇总总结一些常遇到的情况,这次固件会分开发布,以免混淆。 上一个帖子地址:烽火HG680-KA࿰…...
Java数据结构相关知识
文章目录 1. 自动装箱和自动拆箱2. Object的equals方法3. Comparable和Comparator接口 1. 自动装箱和自动拆箱 自动装箱:将基本数据类型自动转换为对应的包装类。自动拆箱:将包装类自动转换为对应的基本数据类型。 显示装箱 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(字符型,账号密码型,get型) 判断闭合方式 在用户名输入1‘,此时密码先输入任何数字时,出现语法错误 说明闭合方式为单引号闭合,在判断完闭合方式后…...
【贪心算法】柠檬水找零
1.题目解析 860. 柠檬水找零 - 力扣(LeetCode) 2.讲解算法原理 分情况讨论 5---》直接收下 10---》找五元,收下 20----》105△ ----》555 由于5元更有用,则尽可能保留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) - 综合案例:管理费用明细表
本篇来实现一个综合案例:管理费用明细表。报表在实际项目中,也有一定的参考意义,一方面展示类似的报表,比如管理费用、研发费用等费用的明细,使用业务比较习惯的展示格式;另一方面正好综合运用前面学习的动…...
通过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 中,当多个选择器同时匹配同一个元素时,浏览器会根据选择器的权重来决定哪个样式生效。权重高的选择器的样式会覆盖权重低的选择器的样式。 二、选择器权重计算规则 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 控制,并通过不同类型的光源 (DirectionalLight、SpotLight、PointLight) 生成。我们将系统地整理与阴影相关的知识点。 1️⃣ 基础概念 castShadow 🎭:物体是否投射阴影。receiveShadow Ἵ…...
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 是两个常用的包安装命令,但它们在很多方面存在差异。 1. 所属管理系统不同 1.1 conda install conda install 是Anaconda和Miniconda发行版自带的包管理工具 conda 的安装命令。conda 是一个跨平台的开源包管理系统和环境管理系统&…...
蓝桥杯备考:特殊01背包问题——》集合subset
我们划分成两个集合,实际上我们只需要看一部分就行了,也就是从集合的所有元素里挑出恰好满足集合总和的一半儿,当然,如果我们的集合总和是奇数的话,我们是无论如何也挑不出刚好一半儿的,因为我们没有小数&a…...
设计模式之外观模式:原理、实现与应用
引言 外观模式(Facade Pattern)是一种结构型设计模式,它通过提供一个统一的接口来简化复杂系统的使用。外观模式隐藏了系统的复杂性,使得客户端可以通过一个简单的接口与系统交互。本文将深入探讨外观模式的原理、实现方式以及实…...
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. 农业需求驱动 我国棉花主产区,种植面积常年超250万公顷,传统人工播种存在两大核心问题: 效率瓶颈:人均日播种面积不足0.5公顷,难以匹配规模化种植需求; 精度缺陷:人…...
【程序人生】成功人生架构图(分层模型)
文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层:调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…...
golang开发支持onlyoffice的token功能
一直都没去弄token这块,想着反正docker run的时候将jwt置为false即可。 看了好多文章,感觉可以试试,但是所有文件几乎都没说思路。 根据我的理解和成功的调试,思路是: 我们先定义2个概念,一个是文档下载…...
Qt for WebAssembly程序中文乱码问题处理过程
一、环境 操作系统DeepinV23 Qt版本6.8.2 编程语言C 二、问题现象 Qt for WebAssembly应用在浏览器页面上英文字母显示正常,中文显示为乱码。 经测试分析原因为默认字体不能正常显示汉字。 三、处理过程 1.准备中文字体文件 从Windows下复制宋体简体字体文件…...
速通大厂测开
最近26届暑期实习招聘和25届春招已经开始,测开学习圈也有同学拿到offer了 今天分享一位25届秋招圈友快速拿到大厂测开offer的经历,希望对大家有所帮助 我是某211本科生,在去年暑假准备考研的间隙意外收获了某大厂测开实习offer,…...
基于Netty实现高性能HTTP反向代理
以下将分步骤实现一个基于Netty的高性能HTTP反向代理,支持动态路由、负载均衡和基础鉴权功能。 1. 项目依赖配置(Maven) 2. 定义路由规则 3. 实现HTTP反向代理服务端 4. 实现反向代理处理器 5. 实现基础鉴权 6. 性能优化策略 连接池管理…...
Spring Boot集成MyBatis与MySQL
Spring Boot集成MyBatis与MySQL开发全攻略 一、前言:现代Java持久层开发的选择 在微服务架构盛行的今天,Spring Boot以其"约定优于配置"的理念成为Java开发的事实标准。结合MyBatis这一灵活高效的ORM框架和MySQL这一成熟稳定的关系型数据库&…...
