1. 程式人生 > >js面向對象案例 貪吃蛇

js面向對象案例 貪吃蛇

val bre 組成 run pre osi 重新 window 獲取

  食物對象

 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,top 40 this.divArr[this.divArr.length - 1].css({ 41 ‘left‘: this.left * this.width, 42 ‘top‘: this.top * this.height 43 }); 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]代表最新生成的食物div
117             //將這個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: 0
124             });
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 }

js面向對象案例 貪吃蛇