好久好久,真的是好久好久没来写过了,因为最近有点小忙。不过即使是忙,也也还是写了两个小游戏,其中一个就是这个,贪吃蛇啦。

算是一个小练手了,这个是在有点太简单了,只是第一次写这种小游戏,还是零零星星花了三五天时间,下面就是这个小游戏的gif小动画,比较简单,对比过网上其他用来写出来练手的贪吃蛇作品,这个在颜值还是功能上,都还是不错的,霍霍。

这里讲解一下功能:

  1. 空格控制开始和暂停。
  2. 方向键控制移动方向。
  3. Q 键加速,再按一次恢复常规速度(在加速状态时,按下或者方向键,或者吃到了白色小食物,速度自动恢复正常)。

这次我研究了 github,一个用来管理代码版本的国外网站,不过使用它不需要FQ,它的一个功能,就是可以用来展示网站,比如我就把贪吃蛇放在里 github 中,可以点击后面的链接访问,也就是可以直接玩耍:点击这里打开贪吃蛇

想描述一下技术要点。。。发现有点小忘了,不过一个难点还是记得的,当蛇的身子比较长后,容易和自己挨住,会连成一块,看上去很不方便,所以我在中间添加了这条缝隙,如下图所示,为添加前和添加后的效果:

这条缝隙的添加还是比较麻烦的,我的思路是,给组成蛇身的每个 li 元素小块,都设置个 1px 的border背景色边框,接着每一个 li 的后面跟一个宽度为 2px,高度和 li 等高的 span 标签,背景颜色和li相同,再通过css设置好位置,正好可以补上蛇身中两个正常相连的 li 小块之间,那个 2px 的缝隙,为什么是 2px 呢?因为前一个 li 和后一个 li,各都有 1px 的 border。

源代码也放在下面吧,免得以后啥时候我改了 github 配置,上面那个链接不能使用了。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>贪吃蛇</title><style>* {padding: 0;margin: 0;}body {background-color: #090e20;}.big {width: 1000px;height: 600px;border: 1px dashed #fff;margin: 30px auto 0;position: relative;}p {margin-bottom: 10px;}.right span {position: absolute;width: 20px;height: 20px;background-color: #fff;border-radius: 30%;}ul li {list-style: none;position: absolute;width: 20px;height: 20px;background-color: #b5cad5;box-sizing: border-box;border: 1px solid #090e20;}ul li b {display:block;z-index: 100;width: 2px;height: 18px;background-color: #b5cad5;position: absolute;top: 0;left: 8px;transform-origin: 11px 9px;transform: translate(-10px,0) rotate(0deg);}ul li:first-child b {width: 4px;transform: translate(-12px,0) rotate(0deg);}ul li:last-child b {background-color: transparent;}ul li:nth-child(1) {border-radius: 0 50% 50% 0;/*transform:scale(2,2);*/}ul li:nth-child(1):before {content: '';display: block;background-color: #090e20;width: 2px;height: 2px;position: absolute;bottom: 5px;right: 10px;z-index: 2;}ul li:nth-child(1):after {content: '';display: block;background-color: #090e20;width: 2px;height: 2px;position: absolute;top: 5px;right: 10px;}.explain {float: left;box-sizing: border-box;border-right: 1px dashed #fff;height: 100%;width: 260px;color: #fff;}.explain em {color: #b3c6ff;font-style: normal;}ol li {margin-left: 25px;}.right {width: 740px;float: right;height: 100%;position: relative;box-sizing: border-box;}</style>
</head>
<body>
<div class="big"><div class="explain"><p>点击<em>空格</em>开始或暂停</p><p>可通过<em>WASD</em>或者<em>方向键</em>控制方向</p><p>可通过<em>回车键</em>或者<em>Q</em>加速</p><p>当改变方向,或者吃到小球,速度自动恢复正常</p><br><p>以下为每局吃掉的小球个数</p><ol></ol></div><div class="right"><span></span><ul></ul></div>
</div>
</body>
<script>window.onload = function () {//获取元素节点var big = document.querySelector(".big");var span = document.querySelector("span");var ul = document.querySelector("ul");var ol = document.querySelector("ol");var ol_lis; //预留的ol中的li标签var lis;//预留的ul中的li标签,即贪吃蛇的身子var times;//速度,初始为150var arrall;//二维数组,每一项为一个数组,其中保存每个li的x轴y轴坐标和方向var timer;//蛇运动时的定时器var timers;//数组,蛇吃到小球,小球白点顺着身子流动的定时器,之所以是数组,是因为可能上一个小球白点还没到尾部,蛇又吃了一个var index;//数组,和times绑定的var direction; //现在蛇运动的方向var flag; //判断是否按下了方向键var num;//用来记忆最初始有几个li,计数吃掉几个小球时减去var stars = false;//判断是否游戏中true或者falsevar spanX;//保存食物小球的坐标var spanY;star();//初始化函数function star() {times = 200;arrall = [];timers = [];index = [];ul.innerHTML = "<li></li><li></li><li></li><li></li>";lis = document.querySelectorAll("ul li");num = lis.length;//给每一个li定位,且记录到arrall中for (var i = lis.length - 1; i >= 0; i--) {var arr = [0, 20 * i, "right"];arrall[arrall.length] = arr;lis[i].style.top = 0;lis[i].style.left = 20 * (lis.length - 1 - i) + "px";var b = document.createElement('b');lis[i].appendChild(b);}//给arrall多造一个子元素,用来为吃到小点后新增的身子赋值;arrall[arrall.length] = [0, 20 * lis.length - 1, "right"];spanPosition();//生成span小球事物timer = null;direction = 'right';flag = null;}//生成小白球函数function spanPosition() {var temp;do {temp = false;spanX = Math.floor(Math.random() * 36) * 20;spanY = Math.floor(Math.random() * 29) * 20;//for循环来保证小白球不会出现在蛇身体的内部for (var i = 0; i < lis.length; i++) {if (spanX == arrall[i][1] &&spanY == arrall[i][0]) {temp = true;break;}}} while (temp);span.style.left = spanX + "px";span.style.top = spanY + "px";span.style.display = "block";}//按下键盘按键document.onkeydown = function (e) {//如果是红的,则屏蔽所有按键if (lis[0].style.backgroundColor === "red") return;//如果是空格键if (e.keyCode == 32) {if (timer) {clearInterval(timer);timer = null;flag = true;} else {timer = setInterval(move, times);flag = false;//如果游戏没有运行,也就是初次启动,而不是暂停后的启动if (!stars) {//如果是失败了,蛇头为红色,此时也屏蔽空格var li = document.createElement('li');li.innerHTML = "吃掉小球数量为:" + (arrall.length - 1 - num) + "枚!";ol.appendChild(li);ol_lis = document.querySelectorAll("ol li");stars = true;}}return;}//如果游戏没有开始开,则其他按键失效if (!stars) return;//如果是回车或者Qif (e.keyCode == 13 || e.keyCode == 81) {if (timer) {clearInterval(timer);if (times == "50") times = 200;else times = 50;timer = setInterval(move, times);} else {if (times == "50") times = 200;else times = 50;}return;}if (flag) return;if (e.keyCode == 38 || e.keyCode == 87) {if (direction == "bottom" || direction == "top") {return;}flag = 'top';} else if (e.keyCode == 37 || e.keyCode == 65) {if (direction == "right" || direction == "left") {return;}flag = 'left';} else if (e.keyCode == 39 || e.keyCode == 68) {if (direction == "left" || direction == "right") {return;}flag = 'right';} else if (e.keyCode == 40 || e.keyCode == 83) {if (direction == "top" || direction == "bottom") {return;}flag = 'bottom';} else {returnValue = false;return;}times = 200;clearInterval(timer);move();}//移动函数function move() {//如果安了方向键,那么为direction赋flag的值if (flag) {direction = flag;}//用for循环依次移动每一个lifor (var i = arrall.length - 1; i >= 0; i--) {if (i == arrall.length - 1) {var arrs = [];arrs[0] = arrall[i - 1][0];arrs[1] = arrall[i - 1][1];arrs[2] = arrall[i - 1][2];arrall[i] = arrs;} else {//如果是第一个li,把它的方向信息及时更新if (i == 0) {arrall[i][2] = direction;} else {//如果不是,把li移动的方向设置为前一个的arrall[i][2] = arrall[i - 1][2];}//根据方向来更新位置switch (arrall[i][2]) {case "top" :arrall[i][0] -= 20;lis[i].style.top = arrall[i][0] + "px";lis[i].querySelector('b').style.transform = "translate(-10px,0) rotate(270deg)";break;case "right" :arrall[i][1] += 20;lis[i].style.left = arrall[i][1] + "px";lis[i].querySelector('b').style.transform = "translate(-10px,0) rotate(0deg)";break;case "bottom" :arrall[i][0] += 20;lis[i].style.top = arrall[i][0] + "px";lis[i].querySelector('b').style.transform = "translate(-10px,0) rotate(90deg)";break;case "left" :arrall[i][1] -= 20;lis[i].style.left = arrall[i][1] + "px";lis[i].querySelector('b').style.transform = "translate(-10px,0) rotate(180deg)";break;}}}lis[0].querySelector('b').style.transform= "translate(-12px,0) rotate(0deg)";//再判断是不是按下了方向键,用来转动蛇头if (flag) {if (flag == "bottom") {lis[0].style.transform = "rotate(90deg)";} else if (flag == "right") {lis[0].style.transform = "rotate(0deg)";} else if (flag == "left") {lis[0].style.transform = "rotate(180deg)";} else if (flag == "top") {lis[0].style.transform = "rotate(270deg)";}flag = null;timer = setInterval(move, times);}//判断是否吃掉了小球if (arrall[0][0] == spanY && arrall[0][1] == spanX) {clearInterval(timer);times = 200;timer = setInterval(move, times);//新产生一枚小球点span.style.display = "none";spanPosition();//下面两个是启动产生小白点的函数定时器index[index.length] = 1;timers[timers.length] = setInterval(dingshi,20,timers.length);}//判断有没有碰到墙壁或自己for (var i = 1; i < lis.length; i++) {if (arrall[0][0] == arrall[i][0] &&arrall[0][1] == arrall[i][1] ||arrall[0][0] < 0 ||arrall[0][0] == 600 ||arrall[0][1] < 0 ||arrall[0][1] == 740) {clearInterval(timer);lis[0].style.zIndex = lis.length;lis[0].style.backgroundColor = "red";stars = false;var tempTimer = setTimeout(function(){lis[0].style.backgroundColor = "#b5cad5";star();},1000);break;}}}//吃掉小球,出现顺着蛇身子移动的白点的函数function dingshi(temp){lis[index[temp]].style.backgroundColor = "#b5cad5";if (index[temp] == lis.length-1) {clearInterval(timers[temp]);//新生成的li的数组,其位置和方向信息等于之前的最后一个livar arr = [arrall[arrall.length - 1][0], arrall[arrall.length - 1][1], arrall[arrall.length - 1][2]];arrall[arrall.length] = arr;//创建新的li元素,并且用另一个函数,给这个li赋值位置和方向信息var li = document.createElement("li");var b = document.createElement('b');li.appendChild(b);ul.appendChild(li);lis = document.querySelectorAll("ul li");lis[lis.length - 1].style.top = arr[0] + "px";lis[lis.length - 1].style.left = arr[1] + "px";ol_lis[ol_lis.length - 1].innerHTML = "吃掉小球数量为:" + (arrall.length - 1 - num) + "枚!";return ;};lis[index[temp]+1].style.backgroundColor = "#fff";index[temp]++;}}
</script>
</html>

  

转载于:https://www.cnblogs.com/qianniaoyu/p/7053912.html

使用前端原生 js,贪吃蛇小游戏相关推荐

  1. JS贪吃蛇小游戏(DOM (html+css+js))

    游戏截图: html部分: <!DOCTYPE html> <html lang="en"> <head><meta charset=&q ...

  2. 前端技术搭建贪吃蛇小游戏(内含源码)

    The sand accumulates to form a pagoda ✨ 写在前面 ✨ 功能介绍 ✨ 页面搭建 ✨ 样式设置 ✨ 逻辑部分 ✨ 写在前面 上周我们实通过前端基础实现了井字游戏,今 ...

  3. 原生JavaScript抒写——贪吃蛇小游戏

    原生JavaScript抒写--贪吃蛇小游戏 文章目录 原生JavaScript抒写--贪吃蛇小游戏 前言 一.需求分析 二.效果展示 三.具体逻辑代码分析 1.首先创建一个html文件,然后我们利用 ...

  4. Snake贪吃蛇小游戏纯js代码

    Snake贪吃蛇小游戏纯js代码 先给个效果图,一样的简单而又纯朴,回归贪吃蛇最原始的状态 还是先分析一下,使用面向对象编程真的降低了编程的难度(只要前期把思路想好,各个类,属性,方法抽象出来),就真 ...

  5. JavaScript制作贪吃蛇小游戏

    目录 效果展示 原理分析 Game.js文档 Snake.js文档 Food.js文档 附上源代码 写了这么久的代码 是否你和我一样感到枯燥乏味了呢? 是否没有前进的动力了呢? 别忘了当时的你踌躇满志 ...

  6. html5实现贪吃蛇小游戏

    实现技术:h5的canvas+原生js 可直接复制,查看效果 <!doctype html> <html> <head> <meta charset=&quo ...

  7. python的pygame库使用方法_python基础教程使用Python第三方库pygame写个贪吃蛇小游戏...

    今天看到几个关于pygame模块的博客和视频,感觉非常有趣,这里照猫画虎写了一个贪吃蛇小游戏,目前还有待完善,但是基本游戏功能已经实现,下面是代码: # 导入模块 import pygame impo ...

  8. 用 typescript 做一个贪吃蛇小游戏

    typescript 做一个贪吃蛇小游戏 搭建环境 创建 tscofig.json 文件 配置如下 {"compilerOptions": {"target": ...

  9. JavaScript 进阶教程(2)---面向对象实战之贪吃蛇小游戏

    目录 1 引言 2 游戏地图 3 游戏对象 3.1 食物对象 3.2 小蛇对象 3.3 游戏对象 4 游戏的逻辑 4.1小蛇的移动 4.2 让蛇自己动起来 4.2.1 自动移动 4.2.2 自调用函数 ...

  10. Golang 控制台百行代码贪吃蛇小游戏

    Golang 并不适合在前端工作,缺少强大的图形图像包和硬件加速包,更适合做成后台服务程序.本文的贪吃蛇小游戏运行与控制台上,其中调用了Window系统kernel32.dll中控制台相关的函数. 项 ...

最新文章

  1. poj2503 Babelfish
  2. uniapp商城_【程序源代码】商城小程序
  3. 粒子滤波(Particle filter)
  4. matlab碎纸拼接相似函数,基于蒙特卡洛算法构建能量函数的碎纸图片拼接方法
  5. mysql统计各部门人数_2021各省份电网报名人数统计!会不会比考研还难?有些省份人数还就多的离谱了。。。...
  6. 常用指令备忘录----持续更新
  7. opencv3计算机视觉+Python(四)
  8. 闭环计算机控制系统的例子,自动控制的举例_自动控制的例子_开环和闭环自动控制系统举例...
  9. ubuntu 安装pyqt IDE使用eric 辛酸史
  10. 迅捷fw325r虚拟服务器设置,迅捷FAST FW325R路由器无线桥接设置方法
  11. 怎样在计算机桌面上安装驱动器,如何安装电脑设备驱动程序?
  12. Java执行引擎工作原理:方法调用
  13. 插座质检报告办理第三方检测
  14. lubuntu-调整分辨率
  15. 说明T1线路的传输速率是1.544Mbps
  16. Mercurial中的hg 命令及注释大全
  17. [转]李战大师-悟透delphi-第二章 DELPHI与WIN32时空
  18. 如何使用智能问答机器人服务
  19. 基于Python web信息旅游管理系统
  20. ILSpy[.NET]反编译工具

热门文章

  1. 《艋舺》:哥混的不是黑道,是友情与义气
  2. 廉价冗余磁盘阵列(RAID)介绍 各级RAID的比较
  3. umeng(友盟)集成
  4. 阿里、腾讯、蚂蚁金服Java技术面试及经验总结(文末分享答案)
  5. 糊涂窗口综合症和Nagle算法
  6. 明七暗七(NC17867)数位dp
  7. [模拟字符串] [洛谷] P2788 数学1(math1)- 加减算式
  8. 在windows上开发linux程序
  9. 【Ruby on Rails 起步(二)】Windows下搭建RubyonRails 3.0.4 + Mongrel 1.2.0 pre + Apache2.2.17服务器
  10. 我的中国工控网(http://www.gongkong.com)博客