时光永远在变迁,你始终要丢下过去。


使用语言

JavaScript 

概述

运用JavaScript  实现简易版《贪吃蛇》。
 
 

Html 页面

  1. 1 <!DOCTYPE html>
  2. 2 <html lang="en">
  3. 3 <head>
  4. 4 <meta charset="UTF-8">
  5. 5 <title>贪吃蛇</title>
  6. 6 <link rel="stylesheet" href="css/style.css">
  7. 7 </head>
  8. 8 <body>
  9. 9 <div id="map"></div>
  10. 10 <h2>使用WSAD 或者 上下左右键 控制方向 </h2>
  11. 11 <script src="js/index.js"></script>
  12. 12 </body>
  13. 13 </html>

CSS 页面

  1. 1 #map {
  2. 2 width: 800px;
  3. 3 height: 600px;
  4. 4 background-color: lightgray;
  5. 5 position: relative;
  6. 6 }

JavaScript 部分

  1. 1 // ---------------------Tools--------------------------
  2. 2
  3. 3
  4. 4 ;(function (window, undefined) {
  5. 5 var Tools = {
  6. 6 getRandom: function (min, max) {
  7. 7 return Math.floor(Math.random() * (max - min + 1)) + min;
  8. 8 }
  9. 9 }
  10. 10 // 暴露Tools给window
  11. 11 window.Tools = Tools;
  12. 12 })(window, undefined)
  13. 13
  14. 14 // -----------------------Food---------------------------
  15. 15 ;(function (window, undefined) {
  16. 16 // 局部作用域
  17. 17 var position = 'absolute';
  18. 18 // 记录上一次创建的食物,为删除做准备
  19. 19 var elements = [];
  20. 20 function Food(options) {
  21. 21 options = options || {};
  22. 22 this.x = options.x || 0;
  23. 23 this.y = options.y || 0;
  24. 24
  25. 25 this.width = options.width || 20;
  26. 26 this.height = options.height || 20;
  27. 27
  28. 28 this.color = options.color || 'green';
  29. 29 }
  30. 30
  31. 31 // 渲染
  32. 32 Food.prototype.render = function (map) {
  33. 33 // 删除之前创建的食物
  34. 34 remove();
  35. 35
  36. 36 // 随机设置x和y的值
  37. 37 this.x = Tools.getRandom(0, map.offsetWidth/this.width - 1) * this.width;
  38. 38 this.y = Tools.getRandom(0, map.offsetHeight/this.height - 1) * this.height;
  39. 39
  40. 40 // 动态创建div 页面上显示的食物
  41. 41 var div = document.createElement('div');
  42. 42 map.appendChild(div);
  43. 43
  44. 44 elements.push(div);
  45. 45
  46. 46 // 设置div的样式
  47. 47 div.style.position = position;
  48. 48 div.style.left = this.x + 'px';
  49. 49 div.style.top = this.y + 'px';
  50. 50 div.style.width = this.width + 'px';
  51. 51 div.style.height = this.height + 'px';
  52. 52 div.style.backgroundColor = this.color;
  53. 53 }
  54. 54
  55. 55 function remove() {
  56. 56 for (var i = elements.length - 1; i >= 0; i--) {
  57. 57 // 删除div
  58. 58 elements[i].parentNode.removeChild(elements[i]);
  59. 59 // 删除数组中的元素
  60. 60 // 删除数组元素
  61. 61 // 第一个参数,从哪个元素开始删除
  62. 62 // 第二个参数,删除几个元素
  63. 63 elements.splice(i, 1);
  64. 64 }
  65. 65 }
  66. 66
  67. 67 // 把Food构造函数 让外部可以访问
  68. 68 window.Food = Food;
  69. 69 })(window, undefined)
  70. 70
  71. 71 // ---------------------------Snake----------------------
  72. 72 ;(function (window, undefined) {
  73. 73 var position = 'absolute';
  74. 74 // 记录之前创建的蛇
  75. 75 var elements = [];
  76. 76 function Snake(options) {
  77. 77 options = options || {};
  78. 78 // 蛇节 的大小
  79. 79 this.width = options.width || 20;
  80. 80 this.height = options.height || 20;
  81. 81 // 蛇移动的方向
  82. 82 this.direction = options.direction || 'right';
  83. 83 // 蛇的身体(蛇节) 第一个元素是蛇头
  84. 84 this.body = [
  85. 85 {x: 3, y: 2, color: 'red'},
  86. 86 {x: 2, y: 2, color: 'blue'},
  87. 87 {x: 1, y: 2, color: 'blue'}
  88. 88 ];
  89. 89 }
  90. 90
  91. 91 Snake.prototype.render = function (map) {
  92. 92 // 删除之前创建的蛇
  93. 93 remove();
  94. 94 // 把每一个蛇节渲染到地图上
  95. 95 for (var i = 0, len = this.body.length; i < len; i++) {
  96. 96 // 蛇节
  97. 97 var object = this.body[i];
  98. 98 //
  99. 99 var div = document.createElement('div');
  100. 100 map.appendChild(div);
  101. 101
  102. 102 // 记录当前蛇
  103. 103 elements.push(div);
  104. 104
  105. 105 // 设置样式
  106. 106 div.style.position = position;
  107. 107 div.style.width = this.width + 'px';
  108. 108 div.style.height = this.height + 'px';
  109. 109 div.style.left = object.x * this.width + 'px';
  110. 110 div.style.top = object.y * this.height + 'px';
  111. 111 div.style.backgroundColor = object.color;
  112. 112 }
  113. 113 }
  114. 114 // 私有的成员
  115. 115 function remove() {
  116. 116 for (var i = elements.length - 1; i >= 0; i--) {
  117. 117 // 删除div
  118. 118 elements[i].parentNode.removeChild(elements[i]);
  119. 119 // 删除数组中的元素
  120. 120 elements.splice(i, 1);
  121. 121 }
  122. 122 }
  123. 123
  124. 124 // 控制蛇移动的方法
  125. 125 Snake.prototype.move = function (food, map) {
  126. 126 // 控制蛇的身体移动(当前蛇节 到 上一个蛇节的位置)
  127. 127 for (var i = this.body.length - 1; i > 0; i--) {
  128. 128 this.body[i].x = this.body[i - 1].x;
  129. 129 this.body[i].y = this.body[i - 1].y;
  130. 130 }
  131. 131 // 控制蛇头的移动
  132. 132 // 判断蛇移动的方向
  133. 133 var head = this.body[0];
  134. 134 switch(this.direction) {
  135. 135 case 'right':
  136. 136 head.x += 1;
  137. 137 break;
  138. 138 case 'left':
  139. 139 head.x -= 1;
  140. 140 break;
  141. 141 case 'top':
  142. 142 head.y -= 1;
  143. 143 break;
  144. 144 case 'bottom':
  145. 145 head.y += 1;
  146. 146 break;
  147. 147 }
  148. 148
  149. 149 // 2.4 判断蛇头是否和食物的坐标重合
  150. 150 var headX = head.x * this.width;
  151. 151 var headY = head.y * this.height;
  152. 152 if (headX === food.x && headY === food.y) {
  153. 153 // 让蛇增加一节
  154. 154 // 获取蛇的最后一节
  155. 155 var last = this.body[this.body.length - 1];
  156. 156 this.body.push({
  157. 157 x: last.x,
  158. 158 y: last.y,
  159. 159 color: last.color
  160. 160 })
  161. 161
  162. 162 // 随机在地图上重新生成食物
  163. 163 food.render(map);
  164. 164 }
  165. 165
  166. 166 }
  167. 167
  168. 168 // 暴露构造函数给外部
  169. 169 window.Snake = Snake;
  170. 170 })(window, undefined)
  171. 171
  172. 172 //----------------------Game---------------------------
  173. 173 ;(function (window, undefined) {
  174. 174 var that; // 记录游戏对象
  175. 175 function Game(map) {
  176. 176 this.food = new Food();
  177. 177 this.snake = new Snake();
  178. 178 this.map = map;
  179. 179 that = this;
  180. 180 }
  181. 181
  182. 182 Game.prototype.start = function () {
  183. 183 // 1 把蛇和食物对象,渲染到地图上
  184. 184 this.food.render(this.map);
  185. 185 this.snake.render(this.map);
  186. 186 // 2 开始游戏的逻辑
  187. 187 // 2.1 让蛇移动起来
  188. 188 // 2.2 当蛇遇到边界游戏结束
  189. 189 runSnake();
  190. 190 // 2.3 通过键盘控制蛇移动的方向
  191. 191 bindKey();
  192. 192 // 2.4 当蛇遇到食物 --- 在snake的move方法中处理
  193. 193 }
  194. 194
  195. 195 // 通过键盘控制蛇移动的方向
  196. 196 function bindKey() {
  197. 197 // document.onkeydown = function () {};
  198. 198 document.addEventListener('keydown', function (e) {
  199. 199 // console.log(e.keyCode);
  200. 200 // 37 - left
  201. 201 // 38 - top
  202. 202 // 39 - right
  203. 203 // 40 - bottom
  204. 204 switch (e.keyCode) {
  205. 205 case 37:
  206. 206 this.snake.direction = 'left';
  207. 207 break;
  208. 208 case 38:
  209. 209 this.snake.direction = 'top';
  210. 210 break;
  211. 211 case 39:
  212. 212 this.snake.direction = 'right';
  213. 213 break;
  214. 214 case 40:
  215. 215 this.snake.direction = 'bottom';
  216. 216 break;
  217. 217
  218. 218 // 65 - left
  219. 219 // 87 - top
  220. 220 // 68 - right
  221. 221 // 83 - bottom
  222. 222
  223. 223 case 65:
  224. 224 this.snake.direction = 'left';
  225. 225 break;
  226. 226 case 87:
  227. 227 this.snake.direction = 'top';
  228. 228 break;
  229. 229 case 68:
  230. 230 this.snake.direction = 'right';
  231. 231 break;
  232. 232 case 83:
  233. 233 this.snake.direction = 'bottom';
  234. 234 break;
  235. 235 }
  236. 236 }.bind(that), false);
  237. 237 }
  238. 238
  239. 239 // 私有的函数 让蛇移动
  240. 240 function runSnake() {
  241. 241 var timerId = setInterval(function () {
  242. 242 // 让蛇走一格
  243. 243 // 在定时器的function中this是指向window对象的
  244. 244 // this.snake
  245. 245 // 要获取游戏对象中的蛇属性
  246. 246 this.snake.move(this.food, this.map);
  247. 247 this.snake.render(this.map);
  248. 248
  249. 249 // 2.2 当蛇遇到边界游戏结束
  250. 250 // 获取蛇头的坐标
  251. 251 var maxX = this.map.offsetWidth / this.snake.width;
  252. 252 var maxY = this.map.offsetHeight / this.snake.height;
  253. 253 var headX = this.snake.body[0].x;
  254. 254 var headY = this.snake.body[0].y;
  255. 255 if (headX < 0 || headX >= maxX) {
  256. 256 alert('Game Over');
  257. 257 clearInterval(timerId);
  258. 258 }
  259. 259
  260. 260 if (headY < 0 || headY >= maxY) {
  261. 261 alert('Game Over');
  262. 262 clearInterval(timerId);
  263. 263 }
  264. 264 }.bind(that), 150);
  265. 265 }
  266. 266
  267. 267 // 暴露构造函数给外部
  268. 268 window.Game = Game;
  269. 269 })(window, undefined)
  270. 270
  271. 271 // -------------------调用------------------
  272. 272 ;(function (window, undefined) {
  273. 273 var map = document.getElementById('map');
  274. 274 var game = new Game(map);
  275. 275 game.start();
  276. 276 })(window, undefined)

运行效果截图

其他补充

这是一个简单的贪吃蛇,很多功能没有实现,喜欢的小伙伴可以继续往下做。

任何时候不要吝啬您的赞美,喜欢就点赞拉~,


PS:

如果,您希望更容易地发现我的新博客,不妨点击一下关注。

如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,

因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【肥肥也】!

JavaScript 实现简易版贪吃蛇(Day_13)的更多相关文章

  1. Javascript基础示例:用JS写简易版贪吃蛇(面向对象)

    废话不多说,代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  2. OC版贪吃蛇

    昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些, ...

  3. TOJ 3973 Maze Again && TOJ 3128 简单版贪吃蛇

    TOJ3973传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3973 时间限制(普通 ...

  4. JavaScript原生实现《贪吃蛇》

    概述 JavaScript原生实现<贪吃蛇>,每吃掉一个食物,蛇的身体会变长,食物会重新换位置. 详细 代码下载:http://www.demodashi.com/demo/10728.h ...

  5. 如何用python制作贪吃蛇以及AI版贪吃蛇

    用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...

  6. JavaScript版—贪吃蛇小组件

    最近在学习JavaScript,利用2周的时间看完了<JavaScript高级编程>,了解了Js是一门面向原型编程的语言,没有像C#语言中的class,也没有私有.公有.保护等访问限制的级 ...

  7. js版贪吃蛇

    之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见 js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://gith ...

  8. JavaScript实践-简单的贪吃蛇小游戏

    实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...

  9. Winfrom 极简版贪吃蛇源码

    该源码是我在百度知识库借助前辈的的经验,加上自己的一点小改动写的一个非常简陋的贪吃蛇小程序.如果你们有更好的改动方案,欢迎评论. 进入主题吧! 1.创建一个桌面应运程序,拖一个定时器控件.这样,程序界 ...

随机推荐

  1. 配置动态刷新RefreshScope注解使用局限性(一)

    在 Spring Cloud 体系的项目中,配置中心主要用于提供分布式的配置管理,其中有一个重要的注解:@RefreshScope,如果代码中需要动态刷新配置,在需要的类上加上该注解就行.本文分享一下 ...

  2. Android通过Web与后台数据库交互

    2021.1.27 更新 已更新新版本博客,更新内容与原文章相比有点多,因此新开了一篇博客,请戳这里. 1 背景 开发一个App与后台数据库交互,基于MySQL+原生JDBC+Tomcat,没有使用D ...

  3. Day14_78_可变长参数

    可变长参数 可变长参数只能在形参列表的最后一个,且只能出现一次. 代码实例 import java.util.Date; public class 可变长参数 { public static void ...

  4. C#中普通缓存的使用

    缓存的概念及优缺点在这里就不多做介绍,当然缓存包含多种有普通缓存.客户端缓存.DNS缓存.反向代理缓存以及分布式缓存等等.今天主要聊一聊C#通过编码来实现普通的缓存.话不多说直接上代码. 一.首先,新 ...

  5. .NET 中的 Worker Service 入门介绍

    翻译自 Steve Gordon 2020年3月30日的文章 <WHAT ARE .NET WORKER SERVICES?> [1] 随着 .NET Core 3.0 的发布,ASP.N ...

  6. WordPress伪静态规则设置

    伪静态:即网站本身是动态网页如.php..asp..aspx等格式,而这类网页还带"?"加参数来读取数据库.开启伪静态后,动态网页即被转换重写成静态网页类型页面. WordPres ...

  7. hdu4126(MST + 树形dp

    题意:       这个题目和hdu4756差不多,是给你一个图,然后是q次改变边的权值,权值只增不减,最后问你每次改变之后的最小树的平均值是多少. 思路:(prim+树形dp)       先跑一边 ...

  8. Python小游戏 -- 猜单词

    Python初学者小游戏:猜单词 游戏逻辑:就像我们曾经英语学习机上的小游戏一样,电脑会从事先预置的词库中抽取单词,然后给出单词的字母数量,给定猜解次数,然后让玩家进行猜测,并给出每次猜测的正确字母与 ...

  9. 堆栈上的舞蹈之释放重引用(UAF) 漏洞原理实验分析

    0x01 前言 释放重引用的英文名名称是 Use After Free,也就是著名的 UAF 漏洞的全称.从字面意思可以看出 After Free 就是释放后的内存空间,Use 就是使用的意思,使用释 ...

  10. 16.PHP_Ajax模拟服务器登录验证

    Ajax模拟登陆验证 index.php <script language="javascript">    var http_request = false;     ...