js面向對象案例 貪吃蛇
阿新 • • 發佈:2018-12-20
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 varmaxX = 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面向對象案例 貪吃蛇