1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <title>JS贪吃蛇游戏</title>
8 <style>
9 * {
10 margin: 0;
11 padding: 0;
12 }
13
14 .box {
15 width: 482px;
16 margin: 0 auto;
17 }
18
19 .box .main {
20 float: left;
21 border: 1px solid #ccc;
22 }
23
24 .box .info {
25 line-height: 60px;
26 }
27
28 .box .info p {
29 float: left;
30 margin-right: 20px;
31 }
32
33 .main .row {
34 overflow: hidden;
35 }
36
37 .main .col,
38 .main .active {
39 float: left;
40 width: 20px;
41 height: 20px;
42 }
43
44 .main .active {
45 background: red;
46 }
47 </style>
48 <script>
49 // 模仿jquery获取元素
50 function $(selector, content) {
51
52 content = content || document;
53
54 var sTag = selector.charAt(),
55 arr = [],
56 allName = content.getElementsByTagName('*');
57
58 if (sTag === '#') {
59
60 selector = selector.substring(1);
61
62 // console.log(selector);
63 return content.getElementById(selector);
64
65 } else if (sTag === '.') {
66
67 selector = selector.substring(1);
68
69 for (var i = 0; i < allName.length; i++) {
70 var sstr = allName[i].className.indexOf(selector);
71
72 if (sstr != -1) {
73 arr.push(allName[i]);
74 };
75 };
76
77 // console.log(arr);
78 return arr;
79
80 } else {
81 return content.getElementsByTagName(selector);
82 };
83 }
84
85 window.onload = function() {
86 var oMap = $('#map');
87 oMap.innerHTML = '';
88
89 var nRow = 20, //行
90 nCol = 20, //列
91 g = 3, //蛇默认蛇身长度
92 x = 0, //蛇头在哪一行
93 y = g - 1, //蛇头在那一列
94 foodX = 0,
95 foodY = 0; //食物的x,y轴位置
96
97 // 蛇的长度
98 var aSnakes = new Array();
99 var timer = null;
100 var score = 0;
101 var speed = 200; //默认初始速度
102 // 添加地图布局
103 var AllCols = new Array();
104 for (var i = 0; i < nRow; i++) {
105 var row = document.createElement('div');
106 row.className = 'row';
107
108 var aRow = new Array();
109 for (var j = 0; j < nCol; j++) {
110 var col = document.createElement('div');
111 col.className = 'col';
112
113 row.appendChild(col)
114
115 aRow[j] = col; //添加col到数组中
116 };
117
118 // 把所有row的col 添加到数组中
119 AllCols[i] = aRow;
120 oMap.appendChild(row)
121 };
122
123 // 循环蛇长度
124 for (var k = 0; k < g; k++) {
125 AllCols[0][k].className = 'col active';
126 aSnakes[k] = AllCols[0][k];
127 };
128
129 // 第一个蛇隐藏
130 function firstHide(obj) {
131 obj[0].className = 'col';
132 }
133
134 // 最后一个蛇,往前挪动
135 function lastShow(obj) {
136 obj[obj.length - 1].className = 'col active';
137 }
138
139 // 控制键盘方向
140 var dir = 'right',
141 oldDir = dir;
142 var fa = false;
143 document.onkeydown = function(ev) {
144 var ev = ev || event;
145
146 // 保存上一个值
147 oldDir = dir;
148
149 dir = ev.keyCode;
150
151 // 排除所有非方向箭
152 if (dir>40 || dir<37) {
153 dir = oldDir;
154 };
155
156
157 // 排除相反方向,如果正在向下移动,按上则无效
158 if (dir == 38 && oldDir == 'bottom') {
159 dir = 'bottom';
160 } else if (dir == 39 && oldDir == 'left') {
161 dir = 'left'
162 } else if (dir == 40 && oldDir == 'top') {
163 dir = 'top'
164 } else if (dir == 37 && oldDir == 'right') {
165 dir = 'right'
166 };
167
168 // 正常行走
169 if (dir == 39) {
170 dir = 'right';
171 } else if (dir == 38) {
172 dir = 'top';
173
174 } else if (dir == 37) {
175 dir = 'left';
176
177 } else if (dir == 40) {
178 dir = 'bottom';
179 }
180
181 };
182
183 // 生成食物坐标
184 function food() {
185 foodX = Math.floor(Math.random() * nRow) //食物在哪一行
186 foodY = Math.floor(Math.random() * nCol) //食物在哪一列
187
188 // 排除在自己身上
189 if (AllCols[foodX][foodY].className == 'col active') {
190 food();
191 } else {
192 AllCols[foodX][foodY].className = 'col active';
193 };
194
195 };
196 food();
197
198 // 蛇吃到虫子新增长度
199 function addSnake() {
200 aSnakes[aSnakes.length] = AllCols[foodX][foodY];
201 g += 1;
202 score += 1;
203
204 if (speed == 100) {
205 speed -= 10
206 } else if (speed == 50) {
207 speed -= 5
208 } else {
209 speed -= 20;
210 };
211
212 document.getElementById('score').innerHTML = score;
213 food();
214 }
215
216 // 游戏结束
217 function gameOver() {
218 alert('游戏结束!');
219 clearTimeout(timer);
220 };
221
222
223 // 检测是否碰到自身
224 function checkMe(arr) {
225 var bflag = true;
226
227 for (var i = 0; i < aSnakes.length; i++) {
228 if (aSnakes[i] == arr) {
229 bflag = false;
230 };
231 };
232
233 return bflag;
234 };
235
236 // 游戏开始
237 function start() {
238
239 switch (dir) {
240 case 'left':
241
242 // 是否撞到墙
243 if (y - 1 >= 0) {
244
245 // 是否吃到自身
246 if (checkMe(AllCols[x][y - 1])) {
247
248 // 蛇尾隐藏
249 firstHide(aSnakes)
250
251
252 if (x == foodX && y - 1 == foodY) {
253 addSnake();
254
255 } else {
256 for (var i = 0; i < aSnakes.length - 1; i++) {
257 aSnakes[i] = aSnakes[i + 1]
258 };
259 aSnakes[g - 1] = AllCols[x][y - 1];
260 };
261
262 // 新蛇头显示
263 lastShow(aSnakes)
264
265 y -= 1;
266
267 timer = setTimeout(start, speed);
268
269 } else {
270 gameOver();
271
272 };
273
274
275 } else {
276 gameOver();
277 };
278
279
280 break;
281
282 case 'top':
283
284 // 是否撞到墙
285 if (x - 1 >= 0) {
286
287 // 是否吃到自身
288 if (checkMe(AllCols[x - 1][y])) {
289
290 // 蛇尾隐藏
291 firstHide(aSnakes)
292
293 if (x - 1 == foodX && y == foodY) {
294 addSnake();
295 } else {
296 for (var i = 0; i < aSnakes.length - 1; i++) {
297 aSnakes[i] = aSnakes[i + 1]
298 };
299 aSnakes[g - 1] = AllCols[x - 1][y];
300 };
301
302 // 新蛇头显示
303 lastShow(aSnakes)
304
305 x -= 1;
306
307 timer = setTimeout(start, speed);
308
309 } else {
310 gameOver();
311
312 };
313
314
315 } else {
316 gameOver();
317 };
318
319
320 break;
321
322 case 'right':
323
324 // 是否撞到墙
325 if (y + 1 < nCol) {
326 // 是否吃到自身
327 if (checkMe(AllCols[x][y + 1])) {
328
329 // 蛇尾隐藏
330 firstHide(aSnakes)
331
332 if (x == foodX && y + 1 == foodY) {
333 addSnake();
334 } else {
335 for (var i = 0; i < aSnakes.length - 1; i++) {
336 aSnakes[i] = aSnakes[i + 1]
337 };
338 aSnakes[g - 1] = AllCols[x][y + 1];
339 };
340
341 // 新蛇头显示
342 lastShow(aSnakes)
343
344 // aSnakes[g - 1] = AllCols[x][y-1]; //倒数第二个
345 // console.log(aSnakes[g - 1],AllCols[x][y - 1]);
346
347 y += 1;
348
349 timer = setTimeout(start, speed);
350
351 } else {
352 gameOver();
353
354 };
355
356
357 } else {
358 gameOver();
359 };
360
361
362 break;
363
364 case 'bottom':
365 // console.log(aSnakes[g - 1]);
366
367 // 是否撞到墙
368 if (x + 1 < nRow) {
369
370 // 是否吃到自身
371 if (checkMe(AllCols[x + 1][y])) {
372
373 // 蛇尾隐藏
374 firstHide(aSnakes)
375
376
377 if (x + 1 == foodX && y == foodY) {
378 addSnake();
379 } else {
380 for (var i = 0; i < aSnakes.length - 1; i++) {
381 aSnakes[i] = aSnakes[i + 1]
382 };
383 aSnakes[g - 1] = AllCols[x + 1][y];
384
385 };
386
387 // 新蛇头显示
388 lastShow(aSnakes)
389
390 x += 1;
391
392 timer = setTimeout(start, speed);
393
394 } else {
395 gameOver();
396
397 };
398
399
400 } else {
401 gameOver();
402 };
403 break;
404 }
405
406 // console.log(aSnakes);
407
408 }
409
410 var oStart = document.getElementById("start");
411 oStart.onclick = function() {
412 start();
413 };
414 };
415 </script>
416 </head>
417
418 <body>
419 <div class="box">
420 <h1>JS贪吃蛇游戏</h1>
421 <div class="info">
422 <p class="text">您的分数:<span id="score">0</span>分</p>
423 <p>按[上下左右]方向键吃虫</p>
424 <input id="start" type="button" value="开始游戏" />
425 </div>
426 <div class="main" id="map"></div>
427 </div>
428 </body>
429
430 </html>
431