<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .content { width: 640px; height: 640px; margin: 0 auto; position: relative; } #snakeWrap { width: 600px; height: 600px; background: #225675; border: 20px solid #7dd9ff; position: relative; } .snakeHead { border-radius: 50%; background-color: red; } .snakeBody { border-radius: 50%; background-color: orange; } .food { border-radius: 50%; background-color: green; } </style> </head> <body> <div> <div id="snakeWrap"></div> </div> </body> <script> var sw = 20, //一个方块的宽 sh = 20, //一个方块的高 tr = 30, //行数 td = 30; //列数 var snake = null, food = null, game = null; //方块构造函数 function Square(x, y, classname) { this.x = x * sw; this.y = y * sh; this.class = classname; this.viewContent = document.createElement("div"); //方块对应的DOM元素 this.viewContent.className = this.class; this.parent = document.getElementById("snakeWrap"); //方块对应的父级 } Square.prototype.create = function () { //创建方块DOM this.viewContent.style.position = "absolute"; this.viewContent.style.width = sw + "px"; this.viewContent.style.height = sh + "px"; this.viewContent.style.left = this.x + "px"; this.viewContent.style.top = this.y + "px"; this.parent.appendChild(this.viewContent); } Square.prototype.remove = function () { this.parent.removeChild(this.viewContent); } //蛇 function Snake() { this.head = null; //储存蛇头信息 this.tail = null //储存蛇尾信息 this.pos = []; //储存蛇的每一个身体的位置 this.directionNum = { left: { x: -1, y: 0 }, right: { x: 1, y: 0 }, up: { x: 0, y: -1 }, down: { x: 0, y: 1 } } } Snake.prototype.init = function () { //创建蛇头 var snakeHead = new Square(2, 0, "snakeHead"); snakeHead.create(); this.head = snakeHead; this.pos.push([2, 0]); //创建蛇身体1 var snakeBody1 = new Square(1, 0, "snakeBody"); snakeBody1.create(); this.pos.push([1, 0]); //创建蛇身体2 var snakeBody2 = new Square(0, 0, "snakeBody"); snakeBody2.create(); this.tail = snakeBody2; this.pos.push([0, 0]); //创建链表关系 snakeHead.last = null; snakeHead.next = snakeBody1; snakeBody1.last = snakeHead; snakeBody1.next = snakeBody2; snakeBody2.last = snakeBody1; snakeBody2.next = null; //给蛇添加一个默认的初始移动方向 this.direction = this.directionNum.right; }; //获取蛇的下一个位置,并进行相应的判断 Snake.prototype.getNextPos = function () { var nextPos = [ this.head.x / sw + this.direction.x, this.head.y / sh + this.direction.y ] //下个点是自己,说明吃到了自己,gg var selfCollied = false; this.pos.forEach(function (value) { if (value[0] == nextPos[0] && value[1] == nextPos[1]) { selfCollied = true; } }) if (selfCollied == true) { this.strategies.dead.call(this); // console.log("吃到自己"); // console.log(selfCollied) return; } //下个点是墙,gg if (nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > td - 1 || nextPos[1] > tr - 1) { this.strategies.dead.call(this); // console.log("撞墙了") return; } //下个点是食物,增加身体 if (food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1]) { console.log("吃到了") this.strategies.eat.call(this); return; } //下个点无东西,走 this.strategies.move.call(this); }; //处理碰撞后要做的事 Snake.prototype.strategies = { move: function (format) { //这个参数用于决定要不要删除蛇尾 //创建一个新的身体(在旧蛇头的位置) var newBody = new Square(this.head.x / sw, this.head.y / sh, 'snakeBody'); newBody.next = this.head.next; newBody.next.last = newBody; newBody.last = null; this.head.remove(); newBody.create(); //创建一个新蛇头 var newHead = new Square(this.head.x / sw + this.direction.x, this.head.y / sh + this.direction.y, 'snakeHead'); newHead.next = newBody; newHead.last = null; newBody.last = newHead; newHead.create(); //蛇身体坐标更新 this.pos.splice(0, 0, [this.head.x / sw + this.direction.x, this.head.y / sh + this.direction.y]) //更新蛇头信息 this.head = newHead; if (!format) { //如果fornat的值为false,表示要删除 this.tail.remove(); this.tail = this.tail.last; this.pos.pop(); } }, eat: function () { this.strategies.move.call(this, true); createFood(); game.score++; }, dead: function () { // game.over(); } } snake = new Snake(); //创建食物 function createFood() { var x = null; var y = null; var include = true; //循环跳出条件,true表示食物坐标在蛇身上继续随机生成 while (include) { x = Math.round(Math.random() * (td - 1)); y = Math.round(Math.random() * (tr - 1)); snake.pos.forEach(function (value) { if (x != value[0] && y != value[1]) { include = false; } }); } food = new Square(x, y, "food"); food.pos = [x, y]; var foodDom = document.querySelector(".food") if (foodDom) { foodDom.style.left = x * sw + "px"; foodDom.style.top = x * sh + "px"; // foodDom.parentElement.removeChild(".food") } else { food.create(); } } //构造游戏逻辑 function Game() { this.timer = null; this.score = 0; } Game.prototype.init = function () { snake.init(); createFood(); document.body.onkeydown = function (ev) { if (ev.keyCode == 37 && snake.direction != snake.directionNum.right) { snake.direction = snake.directionNum.left; } else if (ev.keyCode == 38 && snake.direction != snake.directionNum.down) { snake.direction = snake.directionNum.up; } else if (ev.keyCode == 39 && snake.direction != snake.directionNum.left) { snake.direction = snake.directionNum.right; } else if (ev.keyCode == 40 && snake.direction != snake.directionNum.up) { snake.direction = snake.directionNum.down; } } this.start(); } Game.prototype.start = function () { this.timer = setInterval(function () { snake.getNextPos(); }, 200) } // Game.prototype.over = function () { // clearInterval(this.timer); // //游戏回到最初状态 // var snakeWrap = document.getElementById("snakeWrap"); // snakeWrap.innerHTML = ""; // snake = new Snake(); // game = new Game(); // } game = new Game; game.init(); </script> </html>