首页 > 代码库 > 我也来写一个贪吃蛇

我也来写一个贪吃蛇

  最近工作量好大,好忙,趁周末练练手,花了近3小时写了一个贪吃蛇。

  实现贪吃蛇的功能很简单。

  我就分享一下我实现贪吃蛇看起来在界面上移动并且吃食物长大的原理。

  我建了一个数组list_arr[]来保存贪吃蛇所在的每个格子的id,并建了2个全局变量x和y,监听贪吃蛇头的位置,当然x和y也是贪吃蛇的起始位置。

  那么贪吃蛇移动实际上就是每次从list_arr[]里取出第一个元素(list_arr.shift()方法),取出的第一个元素也可以认为是贪吃蛇的尾巴,然后把这个元素(也就是格子的id)代表的格子的css中的贪吃蛇的样式去掉。然后,把[x, y]这组坐标所代表的格子的id扔进list_arr[]里(list_arr.push()),并给这个格子添加上贪吃蛇的样式。所以实际上每次就操作了2个格子的样式。

  如果贪吃蛇吃食物([x, y]与食物所在坐标相同),那么把食物那个格子的css去掉代表食物的样式并加上贪吃蛇的样式,并且不去掉尾巴,也就是不去掉list_arr[]里的第一个元素所在格子的样式。

  1 <!doctype html>
  2 <head>
  3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  5 <meta name="format-detection" content="telephone=no">
  6 <meta name="apple-mobile-web-app-capable" content="yes">
  7 <meta name="apple-mobile-web-app-status-bar-style" content="black">
  8 <style>
  9     body {
 10         position: relative;
 11         margin: 0;
 12         width: 100vw;
 13         height: 100vh;
 14     }
 15     .wrapper {
 16         padding: 40px 0;
 17     }
 18     .snake-box {
 19         margin: 0 auto;
 20         border-collapse: collapse; 
 21         border:solid #ddd; 
 22         border-width:1px 0px 0px 1px;
 23     }
 24     .snake-box td {
 25         padding: 10px;
 26         border: solid #ddd; 
 27         border-width: 0px 1px 1px 0px; 
 28     }
 29     .snake-body {
 30         background-color: #8078f3;
 31     }
 32     .food {
 33         background-color: #e81616;
 34     }
 35 </style>
 36 </head>
 37 <body>
 38 <div class="wrapper">
 39     <table id="snake_box" class="snake-box">
 40     </table>
 41 </div>
 42 <script>
 43 //Array扩展indexOf
 44 Array.prototype.indexOf = function(val) {
 45     for (var i = 0; i < this.length; i++) {
 46         if (this[i] == val) return i;
 47     }
 48     return -1;
 49 };
 50 
 51 (function() {
 52     var option = {
 53         ‘width‘: 10,    //x轴数量
 54         ‘height‘: 10,    //y轴数量
 55         ‘cell‘: 10,        //暂时无用
 56         ‘speed‘: 400    //setInterval的执行周期 
 57     }
 58     var o = option;
 59 
 60     var snakeBox = document.getElementById(‘snake_box‘);
 61     snakeBox.innerHTML = null;
 62     var fragment = document.createDocumentFragment();
 63     var snakeBoxArray = new Array();
 64     for (var i = 0; i < o.height; i++) {
 65         var sTr = document.createElement(‘tr‘);
 66         sTr.setAttribute(‘class‘, ‘row‘);
 67         var cellFragment = document.createDocumentFragment();
 68         snakeBoxArray[i]=  new Array(); 
 69         for (var j = 0; j < o.width; j++) {
 70             var sTd = document.createElement(‘td‘);
 71             var sId = j + ‘_‘ + i;
 72             sTd.setAttribute(‘id‘, sId);
 73             sTd.setAttribute(‘class‘, ‘cell‘);
 74             cellFragment.appendChild(sTd);
 75             snakeBoxArray[i][j] = j + ‘_‘ + i;
 76         }
 77         fragment.appendChild(sTr).appendChild(cellFragment);
 78     }
 79     snakeBox.appendChild(fragment);
 80     var x = Math.floor(o.width / 2),
 81         y = Math.floor(o.height / 2),
 82         list_arr = [];  //记录蛇的cell
 83     document.getElementById(snakeBoxArray[x][y]).classList.add(‘snake-body‘);
 84     list_arr.push(x + ‘_‘ + y);
 85 
 86     /*实现键盘方向事件,
 87       注释的代码实现按下方向键立即朝指定方向移动一格,以解决按键后函数的响应延迟问题
 88      */
 89     var lastDir = 39; //记录上一次方向
 90     document.onkeydown = control;
 91     function control(e) {
 92         clearInterval(moveEvent)
 93         var dir;
 94         switch(e.keyCode) {
 95             case 37:  //
 96                 if (list_arr.length > 1 && lastDir == 39) {
 97                     dir = 39;
 98                 } else {
 99                     // x--
100                     lastDir = dir = 37;
101                 }
102                 break;
103             case 38:  //
104                 if (list_arr.length > 1 && lastDir == 40) {
105                     dir = 40;
106                 } else {
107                     // y--;
108                     lastDir = dir = 38;
109                 }
110                 break;
111             case 39:  //
112                 if (list_arr.length > 1 && lastDir == 37) {
113                     dir = 37;
114                 } else {
115                     // x++;
116                     lastDir = dir = 39;
117                 }
118                 break;
119             case 40:  //
120                 dir = lastDir == 38 ? 38 : 40;
121                 if (list_arr.length > 1 && lastDir == 38) {
122                     dir = 38;
123                 } else {
124                     // y++;
125                     lastDir = dir = 40;
126                 }
127                 break;
128         }
129         // var head = list_arr.shift();
130         // list_arr.push(x + ‘_‘ + y)
131         // document.getElementById(head).classList.remove(‘snake-body‘);
132         // document.getElementById(snakeBoxArray[y][x]).classList.add(‘snake-body‘);
133         moveEvent = setInterval(move.bind(this, dir), o.speed)  //移动
134     }
135 
136     /*移动函数*/
137     var moveEvent;
138     function move(direction) {
139         switch(direction) {
140             case 37:  //
141                 x--;
142                 break;
143             case 38:  //
144                 y--;
145                 break;
146             case 39:  //
147                 x++;
148                 break;
149             case 40:  //
150                 y++;
151                 break;
152         }
153 
154         /*死亡判定*/
155          var flag = list_arr.indexOf(x + ‘_‘ + y)
156          if (x < 0 || x >= o.width || y < 0 || y >= o.height || flag != -1) {
157              location.reload();
158          }
159         list_arr.push(x + ‘_‘ + y)
160         if (document.getElementById(snakeBoxArray[y][x]).classList.contains(‘food‘)) {
161             document.getElementById(snakeBoxArray[y][x]).classList.remove(‘food‘);
162             document.getElementById(snakeBoxArray[y][x]).classList.add(‘snake-body‘);
163             food();
164         } else {
165             var tail = list_arr.shift();
166             document.getElementById(tail).classList.remove(‘snake-body‘);
167             document.getElementById(snakeBoxArray[y][x]).classList.add(‘snake-body‘);
168         }    
169     }
170     moveEvent = setInterval(move.bind(this, 39), o.speed)  //加载完成就开始移动
171 
172     /*食物*/
173     var foodCell; //食物位置
174     function food() {
175         var foodX = Math.ceil(Math.random() * o.width) - 1,
176             foodY = Math.ceil(Math.random() * o.height) - 1;
177             foodCell = foodX + ‘_‘ + foodY;
178         if (list_arr.indexOf(foodCell) == -1) {
179             document.getElementById(foodCell).classList.add(‘food‘);
180         } else {
181             return food();
182         }
183     }
184     food();
185 })();    
186 
187 </script>
188 </body>
189 </html>

 

我也来写一个贪吃蛇