我也来写一个贪吃蛇
Posted 悠悠洛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我也来写一个贪吃蛇相关的知识,希望对你有一定的参考价值。
最近工作量好大,好忙,趁周末练练手,花了近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>
以上是关于我也来写一个贪吃蛇的主要内容,如果未能解决你的问题,请参考以下文章