把以下代码保存成Snake.html文件,使用Google或360浏览器打开
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8" /> <title>Snake</title> <style> </style> </head> <body> <div style="position: relative"> <div style=" 400px; font-size: 22px; border: 3px solid black;"> 分数:<span id="score"></span> </div> <canvas id="myCanvas">your browser does not support the canvas</canvas> <div id="help" style="position: absolute; left: 420px; top: 40px;"> Esc: 重新开始</br> Enter: 开始/暂停/继续</br> 方向键: 改变蛇的移动方向</br> Ctrl: 切换控制模式(影响手感)</br> 数字1: 加速</br> 数字2: 减速</br> </div> <div id="gameStates" style="position: absolute; left: 420px; top: 200px; color: red"> 控制模式: <span id="controlMode"></span></br> 运动状态: <span id="pause"></span></br> 蛇的方向: <span id="snakeDir"></span></br> 蛇的速度: <span id="snakeSpeed"></span></br> 蛇的长度: <span id="snakeLength"></span></br> <span id="info"></span> </div> </div> </body> <script type="text/javascript"> /* By Problue,2015.10.15 */ var KEY_L = 37; var KEY_U = 38; var KEY_R = 39; var KEY_D = 40; var KEY_RESET = 27 var KEY_PAUSE = 13; var KEY_CHANGE_CONTROL_MODE = 17; var KEY_INC_SPEED = 49; var KEY_DEC_SPEED = 50; var MAP_R = 20; var MAP_C = 20; var SNAKE_LENGTH_MAX = MAP_R * MAP_C; var OBJ_SIZE = 20; var OBJ = { EMPTY: 0, SNAKE_HEAD: 1, SNAKE_BODY: 2, SNAKE_TAIL: 3, FOOD: 4, STONE: 5 }; var colors = ['white', 'midnightblue', 'darkblue', 'mediumblue', 'midnightblue', 'dimgray']; var mapData = " 00000000000000000000 00000000000000000000 00000000000000000000 50000000500000055000 00000000000000005000 00055000000005500000 00050000000000500000 00000550000550000000 00000500000050000000 00000000000000000000 00000000000000000000 00000005000050000000 00000005500550000000 00000500000000500000 00000550000005500000 00050000000000000000 00055000000000050005 00000000000000000000 00000000000000000000 00000000000000000000"; var map = []; var snake = new Snake(); var food = new Point(0, 0); //var time; var pause; var over; var controlQueueMode; var controlQueue = new Queue(); var score; function Snake() { this.nodes = []; this.dir = 0; this.msSpeed = 0; } function Point(x, y) { this.x = x; this.y = y; } Point.prototype.clone = function() { return new Point(this.x, this.y); } Point.prototype.equals = function(other) { if(other === this) return true; if(!(other instanceof Point)) return false; return this.x == other.x && this.y == other.y; } function Queue() { this.arr = []; this.head = 0; this.tail = 0; } Queue.prototype.enQueue = function(elem) { this.tail++; this.arr[this.tail] = elem; } Queue.prototype.deQueue = function() { this.head++; return this.arr[this.head]; } Queue.prototype.empty = function() { return this.head >= this.tail; } Queue.prototype.clear = function() { this.arr.length = 0; this.head = 0; this.tail = 0; } start(); function start() { initGame(); initMap(); initSnake(); drawMap(); showGameStates(); updateScore(); drawSnake(); randFood(); drawObj(food, OBJ.FOOD); } function initGame() { canvas = document.getElementById('myCanvas'); cxt = canvas.getContext('2d'); canvas.width = MAP_C * OBJ_SIZE; canvas.height = MAP_R * OBJ_SIZE; canvas.style.border = '3px solid black'; document.onkeydown = keydown; //time = +new Date; pause = true; over = 0; controlQueueMode = true; score = 0; } function initMap() { for(var r = 0; r < MAP_R; r++) { map.push([]); for(var c = 0; c < MAP_C; c++) { var obj = mapData[r * MAP_C + c] - 0; map[r][c] = obj; } } } function initSnake() { snake.nodes.length = 0; snake.nodes.push(new Point(2, 0)); snake.nodes.push(new Point(1, 0)); snake.nodes.push(new Point(0, 0)); snake.dir = KEY_R; snake.msSpeed = 150; } function keydown(event) { var key = window.event ? event.keyCode : event.which; switch(key) { case KEY_U: if(snake.dir != KEY_D) { snake.dir = key; controlQueue.enQueue(snake.dir); } break; case KEY_D: if(snake.dir != KEY_U) { snake.dir = key; controlQueue.enQueue(snake.dir); } break; case KEY_L: if(snake.dir != KEY_R) { snake.dir = key; controlQueue.enQueue(snake.dir); } break; case KEY_R: if(snake.dir != KEY_L) { snake.dir = key; controlQueue.enQueue(snake.dir); } break; case KEY_RESET: start(); break; case KEY_PAUSE: pause = !pause; if(!pause) { controlQueue.clear(); move(); } break; case KEY_CHANGE_CONTROL_MODE: controlQueueMode = !controlQueueMode; controlQueue.clear(); break; case KEY_INC_SPEED: snake.msSpeed -= 10; break; case KEY_DEC_SPEED: snake.msSpeed += 10; break; default: ; } showGameStates(); } function moveStep() { showGameStates(); var newHead = snake.nodes[0].clone(); var oldTail = snake.nodes[snake.nodes.length - 1].clone(); switch(snake.dir) { case KEY_U: newHead.y--; break; case KEY_R: newHead.x++; break; case KEY_L: newHead.x--; break; case KEY_D: newHead.y++; break; } var coord = '坐标(' + snake.nodes[0].x + ',' + snake.nodes[0].y + ')是'; info(coord + '空'); if((newHead.x > MAP_C - 1 || newHead.x < 0) || (newHead.y > MAP_R - 1 || newHead.y < 0)) { info(coord + '墙壁'); over = 1; return; } if(isInSnake(newHead)) { info(coord + '自己'); over = 2; return; } var thing = map[newHead.y][newHead.x]; if(thing == OBJ.STONE) { info(coord + '石头'); over = 3; return; } if(thing == OBJ.FOOD) { info(coord + '食物'); snake.nodes.push(new Point(0, 0)); map[newHead.y][newHead.x] = OBJ.EMPTY; randFood(); drawObj(food, OBJ.FOOD); updateScore(); showGameStates(); } for(var i = snake.nodes.length - 1; i >= 1; i--) snake.nodes[i] = snake.nodes[i - 1].clone(); snake.nodes[0] = newHead; drawObj(oldTail, OBJ.EMPTY); drawSnake(); } function move() { if(pause) return; if(controlQueueMode && !controlQueue.empty()) snake.dir = controlQueue.deQueue(); moveStep(); if(over) { over = 0; var turn = []; turn[KEY_U] = KEY_R; turn[KEY_D] = KEY_L; turn[KEY_L] = KEY_U; turn[KEY_R] = KEY_D; snake.dir = turn[snake.dir]; } setTimeout(move, snake.msSpeed); } function isInSnake(point) { for(var i = 0; i < snake.nodes.length; i++) if(snake.nodes[i].equals(point)) return true; return false; } function randFood() { function randInt(n, m) { return Math.floor(Math.random() * (m - n)) + n; } function smart(pt) { if(pt.x == snake.nodes[0].x) { if(snake.dir == KEY_U) return pt.x - snake.nodes[0].x < 0; if(snake.dir == KEY_D) return pt.x - snake.nodes[0].x > 0; } if(pt.y == snake.nodes[0].y) { if(snake.dir == KEY_L) return pt.y - snake.nodes[0].y < 0; if(snake.dir == KEY_R) return pt.y - snake.nodes[0].y > 0; } return false; } do { food.x = randInt(0, MAP_C); food.y = randInt(0, MAP_R); } while(isInSnake(food) || smart(food) || map[food.y][food.x] != OBJ.EMPTY); map[food.y][food.x] = OBJ.FOOD; } function info(str) { $('info').innerHTML = str; } function showGameStates() { $('pause').innerHTML = pause ? '静止' : '移动'; $('controlMode').innerHTML = controlQueueMode ? '队列' : '普通'; var toText = []; toText[KEY_L] = '左'; toText[KEY_U] = '上'; toText[KEY_R] = '右'; toText[KEY_D] = '下'; $('snakeDir').innerHTML = toText[snake.dir]; $('snakeSpeed').innerHTML = snake.msSpeed + 'ms/' + OBJ_SIZE + 'px'; $('snakeLength').innerHTML = snake.nodes.length; } function updateScore() { $('score').innerHTML = score++; } function drawMap() { var pt = new Point(0, 0); for(var r = 0; r < MAP_R; r++) { for(var c = 0; c < MAP_C; c++) { if(map[r][c] == OBJ.STONE) { pt.x = c; pt.y = r; drawObj(pt, OBJ.STONE); } } } } function drawSnake() { drawObj(snake.nodes[0], OBJ.SNAKE_HEAD); for(var i = 1; i < snake.nodes.length - 1; i++) drawObj(snake.nodes[i], OBJ.SNAKE_BODY); drawObj(snake.nodes[snake.nodes.length - 1], OBJ.SNAKE_TAIL); } function drawObj(point, type) { cxt.fillStyle = colors[type]; cxt.fillRect(point.x * OBJ_SIZE, point.y * OBJ_SIZE, OBJ_SIZE, OBJ_SIZE); } function $(id) { return document.getElementById(id); } </script> </html>
https://www.cnblogs.com/mq0036/p/4946076.html