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


使用语言

JavaScript 

概述

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

Html 页面

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

CSS 页面

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

JavaScript 部分

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

    节省 95%的内存占用,减少 80%的启动耗时. GraalVM 是一种高性能的虚拟机,它可以显著的提高程序的性能和运行效率,非常适合微服务.最近比较火的 Java 框架 Quarkus 默认支持 G ...

  2. 女娲造人引发思考之Java设计模式:工厂模式

    目录 工厂模式的几种形态 简单工厂模式 示例 结构 优缺点 女娲抟土造人 工厂方法模式 结构 女娲举绳造人 抽象工厂模式 结构 女娲造万物 工厂模式的几种形态 工厂模式专门负责将大量有共同接口的类实例 ...

  3. synchronized锁由浅入深解析

    一:几种锁的概念 1.1 自旋锁 自旋锁,当一个线程去获取锁时,如果发现锁已经被其他线程获取,就一直循环等待,然后不断的判断是否能够获取到锁,一直到获取到锁后才会退出循环. 1.2 乐观锁 乐观锁,是 ...

  4. adb下载安装

    下载地址:https://www.androiddevtools.cn/# 首页tab工具栏: 选择Android SDK工具-- SDK Tools 下载任一版本即可 安装 :将下载的安装包解压到D ...

  5. Oracle-DG最大保护模式下,dg备库出现问题对主库有什么影响?

    一.需求 疑问?Oracle最大保护模式下,dg备库出现问题,影响主库吗? 我们都知道Oracle最大保护模式的意思是oracle不允许数据丢失,1条记录都不行! 那么备库有问题? oracle主库还 ...

  6. 痞子衡嵌入式:利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache. 关于i.MXRT1xxx系列内部通用数据协处 ...

  7. 总结:composer的install和require和update指令。到底什么时候用什么指令

    https://packagist.org  相当于是应用商店

  8. hdu3329 二分+搜索

    题意:       给你一个岛,然后岛的外侧开始涨水(内侧不涨只有外侧,也就是里面的0永远是0),问最少涨水多少才能把岛分成两个或者两个以上. 思路:       可以二分枚举水的高度(数据不大估计暴 ...

  9. UVA11624大火蔓延的迷宫

    题意:     给1个n*m的网格,上面有的点能走,有的点不能走(墙),然后有的点是火源,火源和人一样,每次都是上下左右四个方向蔓延,速度一样是1,火也不可以从墙上跨过去,给你人的起点,终点是只要走到 ...

  10. 使用SSH端口做端口转发以及反向隧道

    目录 SSH做本地端口转发 SSH做反向隧道(远程端口转发) 用autossh建立稳定隧道 SSH开启端口转发需要修改 /etc/ssh/sshd_config配置文件,将 GatewayPorts修 ...