js面向对象案例 贪吃蛇

  食物对象

 1 (function () { 2 //map:所在的父盒子,obj自身的一些属都具有默认值 3 function Food(map, obj) {  4 obj = obj || {}; //没有则使用默认值  5 this.width = obj.width || 20; 6 this.height = obj.height || 20; 7 this.top = obj.top || 0; 8 this.left = obj.left || 0; 9 this.backgroundColor = obj.backgroundColor || ‘green‘;10 this.divArr = [];//存储$("div")的数组11 this.map = map;12  }13 //在页面上用div渲染这个食物14 Food.prototype.render = function () {15 this.divArr.push($(‘<div></div>‘));16 this.divArr[this.divArr.length - 1].css({17 ‘width‘: this.width,18 ‘height‘: this.height,19 ‘position‘: ‘absolute‘,20 ‘backgroundColor‘: this.backgroundColor,21 }).appendTo(this.map);22  }23 //随机生成食物的位置,必须传入snake对象作为参数24 Food.prototype.random = function (snake) {25 var maxX = this.map.width() / this.width - 1;//地图的最大坐标 20px一格26 var maxY = this.map.height() / this.height - 1;27 var x = tools.getRandom(0, maxX); //随机生成x坐标和y坐标 工具对象的方法(在下面贴出 有点画蛇添足)28 var y = tools.getRandom(0, maxY);29 //遍历蛇对象的节点,如果随机生成的食物坐标与蛇节点重叠再次随机食物坐标30 for (var i = 0; i < snake.snakeNode.length; i++) {31 if (x == snake.snakeNode[i].left && y == snake.snakeNode[i].top) {32 x = tools.getRandom(0, maxX);33 y = tools.getRandom(0, maxY);34 i = 0;//再次随机食物坐标后,重置i 再次遍历35  }36  }37 this.left = x;38 this.top = y;39 //在页面上改变食物的left,top40 this.divArr[this.divArr.length - 1].css({ 41 ‘left‘: this.left * this.width,42 ‘top‘: this.top * this.height43  });44  }45 window.Food = Food;46 })()

  工具对象

1 (function(){2 var tools = {3 getRandom:function(min,max){4 return Math.floor(Math.random()*(max - min +1)+min);5  }6  }7 window.tools = tools;8 })()

     snake对象

 1 (function () { 2 //map:所在的父盒子,obj自身的一些属都具有默认值 3 function Snake(map, obj) { 4 obj = obj || {}; //没有则使用默认值  5 this.width = obj.width || 20; 6 this.height = obj.height || 20; 7 this.divArr = []; //存储组成蛇的div盒子 8 this.map = map; 9 this.directionCode = obj.directionCode || 39; 10 this.snakeNode = [{ //初始蛇的节点 11 left: 2, 12 top: 4, 13 background: ‘red‘ 14  }, { 15 left: 1, 16 top: 4, 17 background: ‘blue‘ 18  }, { 19 left: 0, 20 top: 4, 21 background: ‘blue‘ 22  }] 23  } 24 //在页面上用div渲染蛇 25 Snake.prototype.render = function () { 26 //遍历蛇的节点(snakeNode) 27 for (var i = 0, len = this.snakeNode.length; i < len; i++) { 28 this.divArr.push($(‘<div></div>‘));//生成div,将div记录在蛇的divArr中 29 this.divArr[this.divArr.length - 1].css({ 30 ‘width‘: this.width, 31 ‘height‘: this.height, 32 ‘position‘: ‘absolute‘, 33 ‘left‘: this.snakeNode[i].left * this.width, 34 ‘top‘: this.snakeNode[i].top * this.height, 35 ‘backgroundColor‘: this.snakeNode[i].background 36 }).appendTo(this.map); 37  } 38  } 39 //根据蛇的方向(directionCode)改变蛇的节点(snakeNode)的坐标 40 //思路是蛇最后的节点移动到前一个节点位置,直到蛇头根据方向移动一格 41 //37 38 39 40 是上下左右的按键码,65 68 83 87 是WASD的键码 42 //需要参数 定时器的标记(在游戏对象中生成) 43 Snake.prototype.move = function (timgerId) { 44 //蛇身体 45 for (var i = this.snakeNode.length - 1; i > 0; i--) { 46 this.snakeNode[i].left = this.snakeNode[i - 1].left; 47 this.snakeNode[i].top = this.snakeNode[i - 1].top; 48  } 49 //蛇头 50 switch (this.directionCode) { 51 case 39: 52 this.snakeNode[0].left += 1; 53 break; 54 case 37: 55 this.snakeNode[0].left -= 1; 56 break; 57 case 38: 58 this.snakeNode[0].top -= 1; 59 break; 60 case 40: 61 this.snakeNode[0].top += 1; 62 break; 63 case 68: 64 this.snakeNode[0].left += 1; 65 break; 66 case 65: 67 this.snakeNode[0].left -= 1; 68 break; 69 case 87: 70 this.snakeNode[0].top -= 1; 71 break; 72 case 83: 73 this.snakeNode[0].top += 1; 74 break; 75 default: 76 break; 77  } 78 //获取地图的最大坐标,如果蛇头的坐标越界则提示游戏结束 79 var maxX = this.map.width() / this.width; 80 var maxY = this.map.height() / this.height; 81 var snakeHeadX = this.snakeNode[0].left; 82 var snakeHeadY = this.snakeNode[0].top; 83 if (snakeHeadX < 0 || snakeHeadX >= maxX || snakeHeadY < 0 || snakeHeadY >= maxY) { 84 clearInterval(timgerId);//清除定时器,游戏结束 85 alert(‘Game Over‘); 86  } 87  88  } 89 //根据蛇的节点(snakeNode)改变存储在divArr中的div的坐标 90 //感觉删除div 重新生成div 可能会消耗浏览器性能 91 Snake.prototype.change = function () { 92 for (var i = 0, len = this.divArr.length; i < len; i++) { 93 this.divArr[i].css({ 94 ‘left‘: this.snakeNode[i].left * this.width, 95 ‘top‘: this.snakeNode[i].top * this.height, 96 ‘backgroundColor‘: this.snakeNode[i].background 97  }) 98  } 99  }100 //snake的eat方法,需要参数 食物对象 定时器的标记101 Snake.prototype.eat = function (food, timgerId) {102 //判断蛇头与食物坐标是否重合103 var a = this.snakeNode[0].left == food.left;104 var b = this.snakeNode[0].top == food.top;105 //判断蛇头与蛇身坐标是否重合106 for (var i = this.snakeNode.length - 1; i > 0; i--) {107 var c = this.snakeNode[0].left == this.snakeNode[i].left;108 var d = this.snakeNode[0].top == this.snakeNode[i].top;109 if (c && d) {//蛇吃到自己了110  clearInterval(timgerId);111 alert(‘Game Over‘);112  }113  }114 //当蛇头与食物坐标重合115 if (a && b) {116 //food.divArr[food.divArr.length - 1]代表最新生成的食物div117 //将这个div记录在蛇的divArr中,在蛇节点(snakeNode)中追加一个与之对应的节点118 //在蛇移动时 改变节点坐标,然后根据节点坐标 改变这个div的坐标119 this.divArr.push(food.divArr[food.divArr.length - 1]);120 this.snakeNode.push({121 background: ‘blue‘,122 left: 0,123 top: 0124  });125 food.render(); //重新生成食物126 food.random(this);//随机坐标127  }128  }129 window.Snake = Snake;130 })();

  游戏对象

 1 (function () { 2 var that; //存储生成的游戏对象,因为定时器中的this指向window 3 var kCode = 39; //默认值与蛇的方向相同,存储临时方向按键码,因为在蛇移动之前时方向键可以被按多次 4 function Game(map) { 5 this.map = map; 6 this.snake = new Snake(this.map); //生成snake(蛇)对象 7 this.food = new Food(this.map);//生成food(食物)对象 8 that = this; //记录自己 9 this.timgerId = null; //记录定时器(让蛇移动的定时器)10  }11 //通过原型添加一个开始的方法12 Game.prototype.star = function () {13 this.food.render(); //生成(渲染)食物14 this.food.random(this.snake);//随机食物的坐标,参数为snake对象,防止食物在蛇节点(snakeNode)上15 this.snake.render();//生成(渲染)蛇16 kDown(); //开启(onkeydown),记录用户的所按的键码17 runSnake(); //开启定时器,使蛇移动18  }19 20 function kDown() {21 $(window).on(‘keydown‘, function (e) {22 kCode = e.keyCode;//记录用户的所按的键码23  })24  }25 //一个函数,参数 code 临时按键码,用来判断蛇的方向,让蛇无法掉头(方向不能直接从上变下)26 function changingDirectionSuddenly(code) {27 var b = code == 37 || code == 38 || code == 39 || code == 40 || code == 68 || code == 65 || code == 87 || code == 83;28 if (b) {29 if ((that.snake.directionCode === 39 || that.snake.directionCode == 68) && code !== 37 && code !== 65) {30 that.snake.directionCode = code;31  }32 if ((that.snake.directionCode === 37 || that.snake.directionCode == 65) && code !== 39 && code !== 68) {33 that.snake.directionCode = code;34  }35 if ((that.snake.directionCode === 38 || that.snake.directionCode == 87) && code !== 40 && code !== 83) {36 that.snake.directionCode = code;37  }38 if ((that.snake.directionCode === 40 || that.snake.directionCode == 83) && code !== 38 && code !== 87) {39 that.snake.directionCode = code;40  }41  }42 return that.snake.directionCode;43  }44 //蛇移动45 function runSnake() {46 //记录定时器,开启定时器让蛇连续移动47 that.timgerId = setInterval(function () {48 //在蛇移动时判断方向。49 // 如果在用户按下时判断方向,会导致连续按键使蛇掉头(先按左再按下,表现为掉头)50  changingDirectionSuddenly(kCode); 51 // that.snake.eat(that.food, that.timgerId);//调用蛇的eat方法判断蛇是否吃到啥52 // //先吃还是先移动呢?好像没啥区别53 that.snake.move(that.timgerId);//调用蛇的move方法移动蛇节点一个54 that.snake.change();//调用蛇的change方法改变构成蛇的div的坐标55  that.snake.eat(that.food, that.timgerId);56 }, 300)57  }58 59 window.Game = Game;60 })()

   main

1 (function () {2 var game = new Game($(‘#box‘));3  game.star();4 })();

   HTML

 1 <!DOCTYPE html> 2 <html lang="en"> 3  4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 <link rel="stylesheet" href="css/style.css">10 </head>11 12 <body>13 <div id="box">14 </div>15 </body>16 <script src="js/jquery-1.12.2.js"></script>17 <script src="js/tools.js"></script>18 <script src="js/food.js"></script>19 <script src="js/snake.js"></script>20 <script src="js/game.js"></script>21 <script src="js/main.js"></script>22 23 </html>

  CSS

 

1 #box{2  width: 200px;3  height: 160px;4  margin: 0 auto;5  background-image: url(../images/ditu.jpg);//一个正方形图片,没有也不影响6  /* background-color: #3c3c3c; */7  position: relative;8  overflow: hidden;9 }

 

 

 

相关文章