失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 简单的贪吃蛇小游戏。使用的是纯原生 JavaScript 和 HTML CSS

简单的贪吃蛇小游戏。使用的是纯原生 JavaScript 和 HTML CSS

时间:2023-09-05 13:11:19

相关推荐

简单的贪吃蛇小游戏。使用的是纯原生 JavaScript 和 HTML  CSS

这个小游戏是一时兴起。在暑假时写的 。不过当时还比较简陋。

后来开学后 。还没上课。就又拿出来改了改界面。让它看起来更美观,更像贪吃蛇一些。

先展示展示几张图吧。

开始前

开始咯

吃了些小老鼠后:

撞墙或撞到自己后

当时去做这个时,可能是突然的一个想法。但并不是要做一个完整的游戏出来。

所以这里并没有设置关卡模式有些细节也并不关注 。只是去关注了身体移动,吃食物,成长这些主要的问题。

当然,这些主要问题解决,增加其他功能就不是大问题了。

这里我就先说一下我的思路,有兴趣和想法的同学们可以自己先去尝试尝试,或者可以跟我交流交流。

我的思路

身体怎么移动

这是我第一个思考的问题。

我先想,如果只有一个身体节点,也就是一个小圆 。应该怎么去移动。控制方向。

当然这个就简单了。我们先定义一个变量,保存移动方向 。 再定义一个函数,根据方向控制节点的定时移动。 然后监听键盘点击事件。改变方向就可以了。

那么如果有多个节点呢?显然每个节点都使用一个函数去控制它移动是不切实际的。

我们可以联想到火车的节点,转哪由车头驾驶员控制。后面跟着跑就行了

那么蛇身体的其他节点也是同样。它不需要知道方向,它要做的很简单,就是前一个节点在哪,它走了,我就移动到它的位置就可以了。

那么除了头部,其他的节点通过一个跟屁股走的函数就可以完成移动了。

身体怎么成长

成长是在吃到食物后。仅判断一下头节点是否于食物节点位置重合即可。

身体成长还是比较简单的,也就是在尾部增加一个身体节点,但不是一吃到食物就变长。而是原本的最后一个节点移开后再边长。出现的位置顶替了原最后节点的位置。

怎么判断死亡

这个问题也是比较简单的,也是判断头部节点位置的问题。主要撞到自己,也就是与身体的某部位的位置重合或者与墙壁的位置重合了,就结束游戏即可。

demo

HTML

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><link rel="shortcut icon" href="./img/favicon.ico" type="image/x-icon"><title>贪吃蛇</title><link rel="stylesheet" href="./greedySnake.css"></head><body><!-- 墙 --><div class="wall"><!-- 开始按钮 --><div class="start" style="display:block"><div class="tips_con"><text>?</text><ul class="tips"><li><strong>·</strong> 通过键盘的上下左右的键改变贪吃蛇移动的方向</li><li><strong>·</strong> 长按 Shift 键可以加速,松开恢复</li><li><strong>·</strong> 无关卡设置,触墙或身体会死亡</li></ul></div><button onclick="startGame()">开&nbsp;始</button></div><!-- 蛇盒子 --><div class="snake" style="display:block"><!-- <div class="snake-node" id="tryNode"></div> --></div><!-- 食物盒子 --><div class="foods"></div><!-- 得分 --><div id="infoBar"><div>得分:<span id="score">0</span></div></div><!-- 音效 --><audio src="./sounds/eat.wav">播放</audio></div></body><script src="./greedtSnake.js"></script></html>```#### CSS```csshtml,body {padding: 0;margin: 0;background-color: #111d49;overflow: hidden;user-select: none;}/* 背景及边框 */.wall {width: 980px;height: 580px;border: 30px solid transparent;-webkit-border-image: url(./img/wall.png) 30 30 round;border-image: url(./img/wall.png) 30 30 round;margin: 80px auto;background-color: #666bc6;position: relative;}/* 蛇的身体节点 */.snake-node {position: absolute;transform: translate(-50%, -50%);width: 20px;height: 20px;border: 2px solid #010496;border-radius: 50%;background-color: #010496;opacity: 1;}/* 提高蛇头层级 */.snake-node:nth-child(1) {z-index: 2;}/* 眼睛 */.snake-node:nth-child(1)::before {content: "";position: absolute;top: 0;left: -5px;width: 7px;height: 7px;background-color: #000;border: 3px solid #fff;border-radius: 50%;z-index: 2;}/* 眼睛 */.snake-node:nth-child(1)::after {content: "";position: absolute;top: 0;right: -5px;width: 7px;height: 7px;background-color: #000;border: 3px solid #fff;border-radius: 50%;z-index: 2;}/* 食物 */.food {width: 20px;height: 20px;background-image: url(./img/mice.png);background-size: cover;position: absolute;}/* 开始按钮 */.start {position: absolute;top: 50%;left: 50%;width: 200px;height: 100px;background-color: rgba(255, 255, 255, 0.692);transform: translate(-50%, -50%);text-align: center;line-height: 100px;display: none;}button {outline: none;padding: 5px 10px;border-radius: 10px;border: 2px solid #0063bd;background-image: linear-gradient(to bottom, #62ecfc, #029aea, #0061bc);color: #fff;font-size: 16px;font-weight: 600;box-shadow: 1px 2px 4px 2px rgba(0, 0, 0, 0.253);}button:active {background-image: linear-gradient(rgba(53, 53, 53, 0.199), rgb(53, 53, 53, 0.2));}/* 提示框 */.tips_con {position: absolute;top: 4px;right: 4px;width: 22px;height: 22px;background-color: rgba(255, 255, 255, 0.704);border: 1px solid rgb(15, 15, 15);border-radius: 50%;text-align: center;line-height: 22px;color: #000;font-weight: bold;}.tips_con text {display: inline-block;width: 22px;height: 22px;border-radius: 50%;background-color: rgba(255, 255, 255, 0.704);text-align: center;line-height: 22px;color: #000;font-weight: bold;}.tips_con text:hover {background-color: #44bcd1;box-shadow: 0px 0px 0px 1px #44bacf;}.tips_con ul {position: absolute;top: -24px;left: 45px;margin: 0;padding: 0;border: 1px solid rgb(0, 0, 0);background-color: #fff;width: 200px;display: none;}.tips_con ul li {list-style-type: none;padding: 4px 0;}.tips_con text:hover+ul {display: block;}/* 底部分数 */#infoBar {position: absolute;bottom: -30px;left: 50%;height: 28px;line-height: 28px;background-color: rgb(255, 234, 234);padding: 0px 30px;text-align: center;font-size: 17px;transform: translateX(-50%);border: 1px solid #fff;}/* 音效 */audio {visibility: hidden;display: absolute;}

最重要的 JavaScript

window.onload = function () {// 点击开始按钮var start = document.querySelector(".start");// 食物盒子var foods = document.querySelector(".foods");// 蛇盒子const Snake = document.querySelector(".snake");// 自动移动定时器IDvar timer;// 分数const score = document.querySelector("#score");// 音效const audio = document.querySelector("audio");// 设置最大速度和最小速度常量const maxSpeed = 100, minSpeed = 140// 开始游戏startGame = function () {setTimeout(() => {// 隐藏开始按钮start.style.display = "none";// 初始蛇init();// 开始move(2);// 监听方向改变window.addEventListener("keydown", judgeDrec, false);window.addEventListener("keyup", speedDown, false)}, 200);};// 保存蛇头节点var snakeHead// 初始化蛇和食物init = function () {SnakeBodyList = [[490, 290],[490, 310],[490, 330],];Snake.innerHTML = ` <div class="snake-node" id="snakeHead"></div><div class="snake-node"></div><div class="snake-node"></div>`;snakeHead = document.querySelector("#snakeHead")Snake.style.display = "block";addFood();addFood();addFood();addFood();};// 旋转头function rotateHead(dire) {// 1 : 左 ; 2:上; 3:右 ; 4 : 下switch (dire) {case 1: {snakeHead.style.transform = "translate(-50%,-50%) rotate(-90deg)"; // 注意先后顺序。否则会出错break}case 3: {snakeHead.style.transform = "translate(-50%,-50%) rotate(90deg) ";break}case 4: {snakeHead.style.transform = "translate(-50%,-50%) rotate(180deg) ";break}default: {snakeHead.style.transform = " translate(-50%,-50%) rotate(0deg)";}}}// 方向变量let dire = 2;// 设置节流阀let stop = 0;// 移动速度let speed = minSpeed;// 判断方法和同时判断是否加速function judgeDrec(e) {// 1 : 左 ; 2:上; 3:右 ; 4 : 下// 如果加速if (e.keyCode == 16) {// 并且速度小if (speed === minSpeed) {speed = maxSpeed;move(dire);stop = 0;}return}// 设置节流if (stop) {return;}stop = 1;setTimeout(() => {stop = 0;}, speed);// 判断方向switch (e.keyCode) {case 37: {if (dire === 3 || dire === 1) break;move(1);dire = 1;break;}case 38: {if (dire === 4 || dire === 2) break;move(2);dire = 2;break;}case 39: {if (dire === 1 || dire === 3) break;move(3);dire = 3;break;}case 40: {if (dire === 2 || dire === 4) break;move(4);dire = 4;break;}}}// 移动函数function move(direction) {// 旋转头部rotateHead(direction)// 清理上一次的定时器,免得影响移动方向clearInterval(timer);// 判断移动方向并且赋值移动距离const moveT = direction === 2 ? -20 : direction === 4 ? 20 : 0;const moveL = direction === 1 ? -20 : direction === 3 ? 20 : 0;// 设置定时器,定时移动timer = setInterval(() => {const left = SnakeBodyList[0][0] + moveL,top = SnakeBodyList[0][1] + moveT;// 判断是否死亡 ,没有死亡再进行移动if (!ifDeath(top, left))ifGrowth(top, left);}, speed);}// 减少速度function speedDown(e) {if (e.keyCode == 16) {speed = minSpeedmove(dire);}return}// 判断是否死亡 , 返回布尔值 , true 表示死亡function ifDeath(top, left) {let end = falseif (top >= 580 || top <= 0 || left <= 0 || left >= 980) {endGame();end = true}SnakeBodyList.some((v, i) => {if (i === 0) return false;if (v[0] === left && v[1] === top) {endGame();end = truereturn true;}return false;});return end}// 判断是否吃到食物ifGrowth = function (top, left) {// 检测蛇头是否于食物同位置let ifgrowth = foodPosition.some((v, i) => {if (v[0] === top - 10 && v[1] === left - 10) {foodPosition.splice(i, 1);return true;}return false;});if (ifgrowth) {// 播放音效audio.play();// 成长snakeGrowth([left, top], 1);// 增加食物addFood();// 删除吃掉的食物decreaseFood(top - 10, left - 10);return;}// 不成长snakeGrowth([left, top], 0);};// 食物随机生成var foodPosition = [];addFood = function () {// left 0-960 - 20一个单位 -- 0-58的整数// top 0-560 - 20 一个单位 -- 0 -28 的整数// 生成随机位置const left = Math.round(Math.random() * 48) * 20;const top = Math.round(Math.random() * 28) * 20;// 判断会不会与旧食物位置重合let isadd = foodPosition.every((v) => {if (v[0] === top && v[1] === left) {addFood();return false;}return true;});if (isadd) {foodPosition.push([top, left]);const food = `<div class="food" id='food${top}${left}' style='left:${left}px;top:${top}px'></div>`;foods.innerHTML += food;}};// 删除吃掉的食物decreaseFood = function (top, left) {score.innerText = score.innerText / 1 + 10;const id = `food${top}${left}`;foods.removeChild(document.querySelector("#" + id));};// 蛇身体节点位置数组var SnakeBodyList = [[490, 290],[490, 310],[490, 330],];// 蛇的移动和成长snakeGrowth = function (newPositipn, add) {// 增加蛇长度for (let i = 0; i < add; i++) {SnakeBodyList.push(SnakeBodyList[SnakeBodyList.length - 1]);let newNode = document.createElement("div")newNode.setAttribute("class", "snake-node")Snake.append(newNode)newNode = null}// 向位置坐标添加头位置,删除尾部位置if (newPositipn) {SnakeBodyList.unshift(newPositipn);SnakeBodyList.pop();}// 移动身体const SnakeList = document.querySelectorAll(".snake-node");for (let i = 0; i < SnakeBodyList.length; i++) {SnakeList[i].style.left = `${SnakeBodyList[i][0]}px`;SnakeList[i].style.top = `${SnakeBodyList[i][1]}px`;SnakeList[1].style.opacity = 1}};// 游戏终止function endGame() {// 停止移动clearInterval(timer);alert("游戏结束");window.removeEventListener("keydown", judgeDrec, false);// 恢复Snake.innerHTML = "";Snake.style.display = "none";// 回复原始方向dire = 2// 清空食物位置数组foodPosition = [];// 情况食物foods.innerHTML = "";// 清空得分score.innerText = 0;// 显示开始按钮start.style.display = "block";}};

注意

这里我设置了吃掉食物后的音效。大家可以去找一个音效的 URL放入即可。不需要可以删掉相关的代码避免报错蛇的眼睛是伪元素,不是图片,墙和老鼠的图片大家搜一搜换一下URL就可以了。

大家有什么不懂或者有什么高见欢迎评论或私聊。

如果觉得《简单的贪吃蛇小游戏。使用的是纯原生 JavaScript 和 HTML CSS》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。