一、简单介绍

# 1.1 效果展示

# 1.2 实现思路

  • 地图:创建一个 800px * 400px 的 div 元素来充当地图;地图可以看作由 40 x 20 个小 div(宽高都为20px) 元素组成。
  • 食物:创建一个 宽高都为 20px 的 div 充当食物;食物通过 Math.random 分配随机位置。
  • 蛇:创建一个二维数组充当蛇;二维数组存放蛇节(3个蛇身和1个蛇头),一维数组存放蛇节的位置、颜色和下一个蛇节对象。
  • 蛇移动:先移动蛇尾,再移动蛇头。当前移动的蛇节位置为下一个蛇节未移动时的位置。

# 1.3 涉及技术

DOM操作、面向对象、事件操作和间隔函数setInterval

# 1.4 项目结构

二、实现步骤

# 2.1 绘制地图

# 2.1.1 style.css 文件

  1. html,body {
  2. margin:0;
  3. padding: 0;
  4. }
  5. .map {
  6. margin: 100px auto;
  7. text-align: center;
  8. background-color: pink;
  9. position: relative;
  10. }

# 2.1.2 map.js 文件

  1. var Map = function(width,height) {
  2. this.width = width;
  3. this.height = height;
  4. this.id = "map";
  5. }
  6. Map.prototype.showMap = function(containerId) {
  7. // 创建地图并设置样式
  8. var mapDiv = document.createElement("div");
  9. mapDiv.style.width = this.width +"px";
  10. mapDiv.style.height = this.height + "px";
  11. mapDiv.className = this.id;
  12. mapDiv.id = this.id;
  13. // 将创建的地图添加到页面中
  14. document.getElementById(containerId).appendChild(mapDiv);
  15. }

# 2.1.3 game.js 文件创建地图

  1. var Game = function() {
  2. }
  3. Game.prototype.start = function() {
  4. var map = new Map(800, 400); // 长宽数值必须是2的整数倍
  5. map.showMap("container");
  6. }

# 2.1.4 index.html 文件开始游戏

  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>贪吃蛇</title>
  6. <link rel="stylesheet" type="text/css" href="css/style.css">
  7. </head>
  8. <body>
  9. <div id="container"></div>
  10. <script type="text/javascript" src="js/map.js"></script>
  11. <script type="text/javascript" src="js/food.js"></script>
  12. <script type="text/javascript" src="js/snake.js"></script>
  13. <script type="text/javascript" src="js/game.js"></script>
  14. <script type="text/javascript">
  15. window.onload = function() {
  16. var game = new Game();
  17. game.start();
  18. }
  19. </script>
  20. </body>
  21. </html>

# 2.1.5 效果

# 2.2 绘制食物

# 2.2.1 food.js 文件

  1. var Food = function(map) {
  2. this.size = 20; // 食物大小
  3. this.xFood = 0; // 食物x坐标
  4. this.yFood = 0; // 食物y坐标
  5. this.map = map; // 坐在地图
  6. this.foodDiv = null; // 地图中的食物
  7. }
  8. Food.prototype.showFood = function() {
  9. // 此处判断确保地图中只有一个食物
  10. if (this.foodDiv === null) {
  11. // 创建食物并设置样式
  12. this.foodDiv = document.createElement("div");
  13. this.foodDiv.style.width = this.foodDiv.style.height = this.size + "px";
  14. this.foodDiv.style.backgroundColor = "red";
  15. this.foodDiv.style.position = "absolute";
  16. // 将食物添加到地图上
  17. document.getElementById(this.map.id).appendChild(this.foodDiv);
  18. }
  19. // 食物步进值:20px
  20. // 食物权值坐标:X轴(0 - map.width/this.size)Y轴(0 - map.height/this.size)
  21. this.xFood = Math.floor(Math.random() * (this.map.width / this.size));
  22. this.yFood = Math.floor(Math.random() * (this.map.height / this.size));
  23. // 设置食物在地图的位置
  24. this.foodDiv.style.left = this.xFood * this.size + "px";
  25. this.foodDiv.style.top = this.yFood * this.size + "px";
  26. }

# 2.2.2 game.js 文件创建地图和食物对象

  1. var Game = function() {
  2. }
  3. Game.prototype.start = function() {
  4. var map = new Map(800, 400); // 长宽数值必须是2的整数倍
  5. map.showMap("container");
  6. var food = new Food(map);
  7. food.showFood();
  8. }

# 2.2.3 效果

# 2.3 绘制小蛇

# 2.3.1 snake.js 文件

  1. var Snake = function(food) {
  2. this.size = 20;
  3. // 初始化蛇{x坐标,y坐标,颜色,蛇节对象}
  4. this.snakeBody = [
  5. {x:0,y:1,color:"black",obj:null},// 蛇身
  6. {x:1,y:1,color:"black",obj:null},// 蛇身
  7. {x:2,y:1,color:"black",obj:null},// 蛇身
  8. {x:3,y:1,color:"white",obj:null}// 蛇头
  9. ];
  10. this.direction = "right"; // 蛇移动方向
  11. this.food = food; //食物
  12. }
  13. // 显示蛇
  14. Snake.prototype.showSnake = function() {
  15. //遍历蛇节,依次创建
  16. for (var i = 0; i < this.snakeBody.length; i++){
  17. //此处判断为了避免重复创建蛇节
  18. if (this.snakeBody[i].obj == null) {
  19. // 创建蛇节div,设置样式
  20. this.snakeBody[i].obj = document.createElement("div");
  21. this.snakeBody[i].obj.style.width = this.snakeBody[i].obj.style.height = this.size + "px";
  22. this.snakeBody[i].obj.style.backgroundColor = this.snakeBody[i].color;
  23. this.snakeBody[i].obj.style.position = "absolute";
  24. // 追加蛇节
  25. document.getElementById(this.food.map.id).appendChild(this.snakeBody[i].obj);
  26. }
  27. // 设置蛇在地图中的位置
  28. this.snakeBody[i].obj.style.left = this.snakeBody[i].x * this.size + "px";
  29. this.snakeBody[i].obj.style.top = this.snakeBody[i].y * this.size + "px";
  30. }
  31. }

# 2.3.2 game.js 文件创建地图、食物和蛇对象

  1. var Game = function() {
  2. }
  3. Game.prototype.start = function() {
  4. var map = new Map(800, 400); // 长宽数值必须是2的整数倍
  5. map.showMap("container");
  6. var food = new Food(map);
  7. food.showFood();
  8. var snake = new Snake(food);
  9. snake.showSnake();
  10. }

# 2.3.3 效果

# 2.4 小蛇移动

# 2.4.1 snake.js 文件,添加move方法

  1. // 移动蛇
  2. Snake.prototype.move = function() {
  3. // 非蛇头蛇节(当前蛇节的新坐标 为 下个蛇节的旧坐标)
  4. for (var i=0; i<this.snakeBody.length -1; i++) {
  5. this.snakeBody[i].x = this.snakeBody[i+1].x;
  6. this.snakeBody[i].y = this.snakeBody[i+1].y;
  7. }
  8. // 设置蛇头位置
  9. if (this.direction == "right") {
  10. // 蛇头x坐标累加
  11. this.snakeBody[this.snakeBody.length - 1].x += 1;
  12. }
  13. if (this.direction == "left") {
  14. // 蛇头x坐标累加
  15. this.snakeBody[this.snakeBody.length - 1].x -= 1;
  16. }
  17. if (this.direction == "up") {
  18. // 蛇头x坐标累加
  19. this.snakeBody[this.snakeBody.length - 1].y -= 1
  20. }
  21. if (this.direction == "down") {
  22. // 蛇头x坐标累加
  23. this.snakeBody[this.snakeBody.length - 1].y += 1;
  24. }
  25. this.showSnake();
  26. }

# 2.4.2 game.js 文件使用 interval 函数调用蛇对象的move方法

  1. var Game = function() {
  2. }
  3. Game.prototype.start = function() {
  4. var map = new Map(800, 400); // 长宽数值必须是2的整数倍
  5. map.showMap("container");
  6. var food = new Food(map);
  7. food.showFood();
  8. var snake = new Snake(food);
  9. snake.showSnake();
  10. setInterval(function() {
  11. snake.move();
  12. }, 100);
  13. }

# 2.5 控制小蛇移动方向

game.js 添加键盘按下事件

  1. var Game = function() {
  2. }
  3. Game.prototype.start = function() {
  4. var map = new Map(800, 400); // 长宽数值必须是2的整数倍
  5. map.showMap("container");
  6. var food = new Food(map);
  7. food.showFood();
  8. var snake = new Snake(food);
  9. snake.showSnake();
  10. setInterval(function() {
  11. snake.move();
  12. }, 100);
  13. // 键盘控制
  14. document.onkeydown = function(e) {
  15. switch (e.keyCode) {
  16. case 37:
  17. snake.direction = "left";
  18. break;
  19. case 38:
  20. snake.direction = "up";
  21. break;
  22. case 39:
  23. snake.direction = "right";
  24. break;
  25. case 40:
  26. snake.direction = "down";
  27. break;
  28. }
  29. snake.showSnake();
  30. }
  31. }

# 2.6 小蛇吃食物

snake.js 文件在 move 方法 this.showSnake() 之前添加逻辑判断

  1. // 蛇头坐标
  2. var xSnakeHead = this.snakeBody[this.snakeBody.length -1].x;
  3. var ySnakeHead = this.snakeBody[this.snakeBody.length -1].y;
  4. //判断蛇吃否吃到食物
  5. if (xSnakeHead == this.food.xFood && ySnakeHead == this.food.yFood) {
  6. // 增加蛇长
  7. var newBody = {x:this.snakeBody[0].x,y:this.snakeBody[0].y,color:"black",obj:null};
  8. this.snakeBody.unshift(newBody);
  9. // 食物消失,再随机生成
  10. this.food.showFood();
  11. }

# 2.7 小蛇移动范围

snake.js 文件在 move 方法 this.showSnake() 之前添加逻辑判断

  1. // 控制小蛇移动范围
  2. if (xSnakeHead < 0 || xSnakeHead >= this.food.map.width/this.size
  3. || ySnakeHead <0 || ySnakeHead >= this.food.map.height/this.size) {
  4. alert("游戏结束!");
  5. window.location.reload();
  6. }
  7. // 不能吃自己
  8. for (var j=0; j<this.snakeBody.length -1; j++) {
  9. // 蛇头坐标 = 蛇身坐标,游戏结束
  10. if (this.snakeBody[j].x == xSnakeHead && this.snakeBody[j].y == ySnakeHead) {
  11. alert("游戏结束!");
  12. window.location.reload();
  13. }
  14. }

三、源码下载

贪吃蛇下载