贪吃蛇js代码
一段贪吃蛇代码,可两个人一起玩,更多人玩可以自己修改,目前可以对战射击,其它玩法自己添加吧。
体验一下:https://oleolema.github.io/snake/
1 <html> 2 3 <head> 4 <meta charset="utf-8"> 5 <title>canvas</title> 6 7 </head> 8 9 <body> 10 11 </body> 12 <!-- <script src="snake.js" ></script> --> 13 <!-- <script src="boll.js"></script> --> 14 <script> 15 /**贪吃蛇 */ 16 17 var canvas = document.createElement('canvas'); 18 var ctx = canvas.getContext('2d'); 19 canvas.style.border = '1px solid black'; 20 canvas.width = window.innerWidth - 30; 21 canvas.height = window.innerHeight - 30; 22 document.body.appendChild(canvas); 23 alert('P1:w,s,a,d,g 分别为上下左右和射击\n\ 24 P2:方向键上下左右加数字键1射击\n\ 25 蛇越长,屏幕上可同时出现的子弹越多'); 26 27 function rand(a, b) { 28 return Math.random() * (b - a) + a; 29 } 30 function randColor(a, b, opacity) { 31 a = a || 0x000000; 32 b = b || 0xffffff; 33 opacity = Number(opacity) || 255; 34 opacity = parseInt(opacity).toString(16); 35 var color = parseInt(rand(Number(a), Number(b))).toString(16); 36 var colorLen = color.length; 37 for (var i = 0; i < 6 - colorLen; i++) { 38 color = '0' + color; 39 } 40 return '#' + color + opacity; 41 } 42 43 function Arms() { 44 45 } 46 47 function Snake(length, bulletColor) { 48 this.x = 1; //头x坐标 49 this.y = 0; //头y坐标 50 this.width = 30; //宽度 51 this.length = length || 3; //长度 52 this.degree = 2; //难度 53 this.speed = []; //速度 54 this.body = []; //身体 55 this.bullet = []; //子弹 56 this.bulAtt = { 57 r: 10, 58 power: 1 59 }; //子弹属性 60 var startY = parseInt(rand(this.width, canvas.height - this.width) / this.width) * this.width; 61 //初始化蛇 62 for (var i = 1; i <= this.width; i++) { 63 if (this.width % i == 0) { 64 this.speed.push(i); 65 } 66 } 67 for (var i = 0; i < this.length; i++) { 68 this.body.push({ 69 x: this.width * this.length - this.width * i, 70 y: startY, 71 dx: 1, 72 dy: 0, 73 color: randColor(0x222222, 0xeeeeee, 0xaa) 74 }); 75 } 76 this.nextDegree = function () { 77 if (this.degree == this.speed.length - 1) { 78 return this.degree; 79 } 80 this.degree++; 81 return this.degree; 82 } 83 this.fire = function () { 84 this.bullet.push({ 85 x: this.body[0].x, 86 y: this.body[0].y, 87 r: this.bulAtt.r, 88 dx: this.body[0].dx, 89 dy: this.body[0].dy, 90 power: this.bulAtt.power, 91 speed: this.speed[this.degree + 2], 92 color: bulletColor 93 }); 94 } 95 this.print = function () { 96 for (i in this.bullet) { //渲染子弹 97 ctx.beginPath(); 98 ctx.arc(this.bullet[i].x, this.bullet[i].y, this.bullet[i].r, 0, 2 * Math.PI); 99 ctx.fillStyle = this.bullet[i].color; 100 ctx.fill(); 101 } 102 for (i in food.food) { //渲染食物 103 ctx.beginPath(); 104 ctx.arc(food.food[i].x, food.food[i].y, this.width / 2, 0, 2 * Math.PI); 105 ctx.fillStyle = food.food[i].color; 106 ctx.fill(); 107 } 108 for (i in this.body) { //渲染蛇 109 ctx.beginPath(); 110 ctx.arc(this.body[i].x, this.body[i].y, this.width / 2, 0, 2 * Math.PI); 111 ctx.fillStyle = this.body[i].color; 112 ctx.fill(); 113 } 114 } 115 this.move = function () { 116 if (this.body[0].x % this.width == 0 && this.body[0].y % this.width == 0) { //转弯 必须在每个球直径的倍数处转弯才能保证垂直 117 for (var i = this.body.length - 1; i > 0; i--) { 118 this.body[i].x += this.body[i - 1].dx * this.speed[this.degree]; 119 this.body[i].y += this.body[i - 1].dy * this.speed[this.degree]; 120 this.body[i].dx = this.body[i - 1].dx; 121 this.body[i].dy = this.body[i - 1].dy; 122 } 123 this.body[0].x += this.x * this.speed[this.degree]; 124 this.body[0].y += this.y * this.speed[this.degree]; 125 this.body[0].dx = this.x; 126 this.body[0].dy = this.y; 127 } else { 128 for (var i = this.body.length - 1; i > 0; i--) { 129 this.body[i].x += this.body[i].dx * this.speed[this.degree]; 130 this.body[i].y += this.body[i].dy * this.speed[this.degree]; 131 } 132 this.body[0].x += this.body[0].dx * this.speed[this.degree]; 133 this.body[0].y += this.body[0].dy * this.speed[this.degree]; 134 } 135 this.bulletMove(); 136 food.isEatFood(); 137 this.overWall(); 138 // this.isSnake(); 139 } 140 this.bulletMove = function () { 141 for (i in this.bullet) { 142 this.bullet[i].x += this.bullet[i].speed * this.bullet[i].dx; 143 this.bullet[i].y += this.bullet[i].speed * this.bullet[i].dy; 144 for (j in snake) { 145 if (snake[j] == this) { 146 continue; 147 } 148 for (k in snake[j].body) { 149 if (Math.abs(snake[j].body[k].x - this.bullet[i].x) <= (snake[j].width + this.bullet[i].r) / 2 && Math.abs(snake[j].body[k].y - this.bullet[i].y) <= (snake[j].width + this.bullet[i].r) / 2) { 150 if (snake[j].body.length <= 1) { 151 gameOver(); 152 return; 153 } 154 // this.bullet[i].power--; 155 this.bullet[i].y = -999; 156 this.bullet[i].dy = 0; 157 snake[j].body.pop(); 158 var lastBody = this.body[this.body.length - 1]; 159 this.body.push({ 160 x: lastBody.x - this.width * lastBody.dx, 161 y: lastBody.y - this.width * lastBody.dy, 162 dx: lastBody.dx, 163 dy: lastBody.dy, 164 color: randColor(0x222222, 0xeeeeee, 0xaa) 165 }); 166 } 167 } 168 } 169 } 170 if (this.bullet.length > 0 && (this.bullet[this.bullet.length - 1].x < 0 || this.bullet[this.bullet.length - 1].y < 0 || this.bullet[this.bullet.length - 1].x > canvas.width || this.bullet[this.bullet.length - 1].y > canvas.height)) { 171 var len = this.bullet.length; 172 for (var i = 0; i < len; i++) { 173 this.bullet.pop(); 174 } 175 } 176 } 177 this.overWall = function () { 178 for (i in this.body) { 179 if (this.body[i].x == 0) { 180 this.body[i].x = parseInt(canvas.width / this.width) * this.width; 181 } 182 else if (this.body[i].x == parseInt(canvas.width / this.width) * this.width) { 183 this.body[i].x = this.width; 184 } 185 else if (this.body[i].y == 0) { 186 this.body[i].y = parseInt(canvas.height / this.width) * this.width; 187 } 188 else if (this.body[i].y == parseInt(canvas.height / this.width) * this.width) { 189 this.body[i].y = this.width; 190 } 191 } 192 } 193 this.isWall = function () { 194 if (this.body[0].x < 0 || this.body[0].y < 0 || this.body[0].x > canvas.width || this.body[0].y > canvas.height) { 195 gameOver(); 196 } 197 } 198 this.isSnake = function () { 199 for (var i = 1; i < this.body.length; i++) { 200 if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) { 201 gameOver(); 202 return; 203 } 204 } 205 } 206 } 207 208 function Food() { 209 this.food = []; 210 for (var i = 0; i < snake.length; i++) { 211 this.food.push( 212 { 213 x: parseInt(rand(snake[i].width, canvas.width - snake[i].width) / snake[i].width) * snake[i].width, 214 y: parseInt(rand(snake[i].width, canvas.height - snake[i].width) / snake[i].width) * snake[i].width, 215 color: randColor(0x222222, 0xeeeeee, 0xaa) 216 }); 217 } 218 this.isEatFood = function () { 219 for (i in snake) { 220 for (k in this.food) { 221 if (snake[i].body[0].x == this.food[k].x && snake[i].body[0].y == this.food[k].y) { 222 snake[i].body[0].color = this.food[k].color; 223 while (true) { 224 this.food[k].x = parseInt(rand(snake[i].width, canvas.width - snake[i].width) / snake[i].width) * snake[i].width; 225 this.food[k].y = parseInt(rand(snake[i].width, canvas.height - snake[i].width) / snake[i].width) * snake[i].width; 226 this.food[k].color = randColor(0x222222, 0xeeeeee, 0xaa); 227 for (j in snake[i].body) { 228 if (this.food[k].x == snake[i].body[j].x && this.food[k].y == snake[i].body[j].y) { 229 break; 230 } 231 } 232 break; 233 } 234 var lastBody = snake[i].body[snake[i].body.length - 1]; 235 snake[i].body.push({ 236 x: lastBody.x - snake[i].width * lastBody.dx, 237 y: lastBody.y - snake[i].width * lastBody.dy, 238 dx: lastBody.dx, 239 dy: lastBody.dy, 240 color: randColor(0x222222, 0xeeeeee, 0xaa) 241 }); //蛇身长长 242 //clearInterval(gameInterval); 243 //gameInterval = setInterval(beginGame, globalTime--); //速度加快 244 } 245 } 246 } 247 } 248 } 249 250 var globalTime = 20; 251 var gameInterval; 252 var snake = [new Snake(3, '#000000'), new Snake(3, '#ff0000')]; //可添加蛇的数量 253 var food = new Food(); 254 var beginGame = function () { 255 ctx.clearRect(0, 0, canvas.width, canvas.height); 256 for (i in snake) { 257 snake[i].print(); 258 snake[i].move(); 259 } 260 } 261 var gameOver = function () { 262 console.info('over'); 263 clearInterval(gameInterval); 264 var msg = 'over\n'; 265 for (i in snake) { 266 msg += 'play' + i + ' : ' + (snake[i].body.length - 3) + '分\n'; 267 } 268 alert(msg + '刷新继续'); 269 } 270 gameInterval = setInterval(beginGame, globalTime--); 271 272 document.onkeydown = function (event) { 273 try { 274 operateSnake(snake[0], 65, 87, 68, 83, 71); 275 operateSnake(snake[1], 37, 38, 39, 40, 105); //操控蛇的方式 276 } 277 catch (e) { 278 console.info(e); 279 } 280 function operateSnake(snake, a, b, c, d, e) { 281 if (event.keyCode == a && snake.body[0].dx != 1 && snake.body[0].dy != 0) { //左 282 snake.x = -1; 283 snake.y = 0; 284 } 285 if (event.keyCode == b && snake.body[0].dx != 0 && snake.body[0].dy != 1) { //上 286 snake.x = 0; 287 snake.y = -1; 288 } 289 if (event.keyCode == c && snake.body[0].dx != -1 && snake.body[0].dy != 0) { //右; 290 snake.x = 1; 291 snake.y = 0; 292 } 293 if (event.keyCode == d && snake.body[0].dx != 0 && snake.body[0].dy != -1) { //下 294 snake.x = 0; 295 snake.y = 1; 296 } 297 if (event.keyCode == e) { //fire 298 if (snake.bullet.length > snake.body.length - 1) { 299 return; 300 } 301 snake.fire(); 302 } 303 } 304 } 305 306 console.info('begin'); 307 </script> 308 309 </html>
BY oleolema