时光永远在变迁,你始终要丢下过去。
使用语言
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: