javascript:用原生js模擬貪吃蛇遊戲練習

本次練習全部的代碼:能夠直接複製所有而後運行看效果~html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <title>title</title>
 6   <style>
 7  .map {
 8  width: 800px;
 9  height: 600px;
 10  background-color: #CCC;
 11  position: relative;
 12     }
 13   </style>
 14 </head>
 15 <body>
 16 <!--畫出地圖,設置樣式-->
 17 <div class="map"></div>
 18 <script>
 19 
 20 
 21   //自調用函數----食物的
 22  (function () {  23     var elements = [];//用來保存每一個小方塊食物的
 24     //食物就是一個對象,有寬,有高,有顏色,有橫縱座標,先定義構造函數,而後建立對象
 25     function Food(x, y, width, height, color) {  26       //橫縱座標
 27       this.x = x || 0;  28       this.y = y || 0;  29       //寬和高
 30       this.width = width || 20;  31       this.height = height || 20;  32       //背景顏色
 33       this.color = color || "green";  34  }  35 
 36     //爲原型添加初始化的方法(做用:在頁面上顯示這個食物)
 37     //由於食物要在地圖上顯示,因此,須要地圖的這個參數(map---就是頁面上的.class=map的這個div)
 38  Food.prototype.init = function (map) {  39       //先刪除這個小食物
 40       //外部沒法訪問的函數
 41  remove();  42 
 43       //建立div
 44       var div = document.createElement("div");  45       //把div加到map中
 46  map.appendChild(div);  47       //設置div的樣式
 48  div.style.width = this.width + "px";  49  div.style.height = this.height + "px";  50  div.style.backgroundColor = this.color;  51       //先脫離文檔流
 52  div.style.position = "absolute";  53       //隨機橫縱座標
 54       this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;  55       this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;  56  div.style.left = this.x + "px";  57  div.style.top = this.y + "px";  58 
 59       //把div加入到數組elements中
 60  elements.push(div);  61  };  62 
 63     //私有的函數---刪除食物的
 64     function remove() {  65       //elements數組中有這個食物
 66       for (var i = 0; i < elements.length; i++) {  67         var ele = elements[i];  68         //找到這個子元素的父級元素,而後刪除這個子元素
 69  ele.parentNode.removeChild(ele);  70         //再次把elements中的這個子元素也要刪除
 71  elements.splice(i, 1);  72  }  73  }  74 
 75     //把Food暴露給Window,外部能夠使用
 76  window.Food = Food;  77  }());  78 
 79   //自調用函數---小蛇
 80  (function () {  81     var elements = [];//存放小蛇的每一個身體部分
 82     //小蛇的構造函數
 83     function Snake(width, height, direction) {  84       //小蛇的每一個部分的寬
 85       this.width = width || 20;  86       this.height = height || 20;  87       //小蛇的身體
 88       this.body = [  89  {x: 3, y: 2, color: "red"},//
 90  {x: 2, y: 2, color: "orange"},//身體
 91  {x: 1, y: 2, color: "orange"}//身體
 92  ];  93       //方向
 94       this.direction = direction || "right";  95  }  96 
 97     //爲原型添加方法--小蛇初始化的方法
 98  Snake.prototype.init = function (map) {  99       //先刪除以前的小蛇
100  remove();//===========================================
101 
102       //循環遍歷建立div
103       for (var i = 0; i < this.body.length; i++) { 104         //數組中的每一個數組元素都是一個對象
105         var obj = this.body[i]; 106         //建立div
107         var div = document.createElement("div"); 108         //把div加入到map地圖中
109  map.appendChild(div); 110         //設置div的樣式
111  div.style.position = "absolute"; 112  div.style.width = this.width + "px"; 113  div.style.height = this.height + "px"; 114         //橫縱座標
115  div.style.left = obj.x * this.width + "px"; 116  div.style.top = obj.y * this.height + "px"; 117         //背景顏色
118  div.style.backgroundColor = obj.color; 119         //方向暫時不定
120         //把div加入到elements數組中----目的是爲了刪除
121  elements.push(div); 122  } 123  }; 124 
125     //爲原型添加方法---小蛇動起來
126  Snake.prototype.move = function (food, map) { 127       //改變小蛇的身體的座標位置
128       var i = this.body.length - 1;//2
129       for (; i > 0; i--) { 130         this.body[i].x = this.body[i - 1].x; 131         this.body[i].y = this.body[i - 1].y; 132  } 133       //判斷方向---改變小蛇的頭的座標位置
134       switch (this.direction) { 135         case "right": 136           this.body[0].x += 1; 137           break; 138         case "left": 139           this.body[0].x -= 1; 140           break; 141         case "top": 142           this.body[0].y -= 1; 143           break; 144         case "bottom": 145           this.body[0].y += 1; 146           break; 147  } 148 
149       //判斷有沒有吃到食物
150       //小蛇的頭的座標和食物的座標一致
151       var headX=this.body[0].x*this.width; 152       var headY=this.body[0].y*this.height; 153       //判斷小蛇的頭的座標和食物的座標是否相同
154       if(headX==food.x&&headY==food.y){ 155         //獲取小蛇的最後-的尾巴
156         var last=this.body[this.body.length-1]; 157         //把最後的蛇尾複製一個,從新的加入到小蛇的body中
158         this.body.push({ 159  x:last.x, 160  y:last.y, 161  color:last.color 162  }); 163         //把食物刪除,從新初始化食物
164  food.init(map); 165  } 166  }; 167 
168     //刪除小蛇的私有的函數=============================================================================
169     function remove() { 170       //刪除map中的小蛇的每一個div,同時刪除elements數組中的每一個元素,從蛇尾向蛇頭方向刪除div
171       var i = elements.length - 1; 172       for (; i >= 0; i--) { 173         //先從當前的子元素中找到該子元素的父級元素,而後再弄死這個子元素
174         var ele = elements[i]; 175         //從map地圖上刪除這個子元素div
176  ele.parentNode.removeChild(ele); 177  elements.splice(i, 1); 178  } 179  } 180 
181     //把Snake暴露給window,外部能夠訪問
182  window.Snake = Snake; 183  }()); 184 
185   //自調用函數---遊戲對象================================================
186  (function () { 187 
188     var that = null;//該變量的目的就是爲了保存遊戲Game的實例對象-------
189 
190     //遊戲的構造函數
191     function Game(map) { 192       this.food = new Food();//食物對象
193       this.snake = new Snake();//小蛇對象
194       this.map = map;//地圖
195  that = this;//保存當前的實例對象到that變量中-----------------此時that就是this
196  } 197 
198     //初始化遊戲-----能夠設置小蛇和食物顯示出來
199  Game.prototype.init = function () { 200       //初始化遊戲
201       //食物初始化
202       this.food.init(this.map); 203       //小蛇初始化
204       this.snake.init(this.map); 205       //調用自動移動小蛇的方法========================||調用了小蛇自動移動的方法
206       this.runSnake(this.food, this.map); 207       //調用按鍵的方法
208       this.bindKey();//========================================
209  }; 210 
211     //添加原型方法---設置小蛇能夠自動的跑起來
212  Game.prototype.runSnake = function (food, map) { 213 
214       //自動的去移動
215       var timeId = setInterval(function () { 216         //此時的this是window
217         //移動小蛇
218         this.snake.move(food, map); 219         //初始化小蛇
220         this.snake.init(map); 221         //橫座標的最大值
222         var maxX = map.offsetWidth / this.snake.width; 223         //縱座標的最大值
224         var maxY = map.offsetHeight / this.snake.height; 225         //小蛇的頭的座標
226         var headX = this.snake.body[0].x; 227         var headY = this.snake.body[0].y; 228         //橫座標
229         if (headX < 0 || headX >= maxX) { 230           //撞牆了,中止定時器
231  clearInterval(timeId); 232  alert("遊戲結束"); 233  } 234         //縱座標
235         if (headY < 0 || headY >= maxY) { 236           //撞牆了,中止定時器
237  clearInterval(timeId); 238  alert("遊戲結束"); 239  } 240  }.bind(that), 150); 241  }; 242 
243     //添加原型方法---設置用戶按鍵,改變小蛇移動的方向
244  Game.prototype.bindKey=function () { 245 
246       //獲取用戶的按鍵,改變小蛇的方向
247  document.addEventListener("keydown",function (e) { 248         //這裏的this應該是觸發keydown的事件的對象---document,
249         //因此,這裏的this就是document
250         //獲取按鍵的值
251         switch (e.keyCode){ 252           case 37:this.snake.direction="left";break; 253           case 38:this.snake.direction="top";break; 254           case 39:this.snake.direction="right";break; 255           case 40:this.snake.direction="bottom";break; 256  } 257  }.bind(that),false); 258  }; 259 
260     //把Game暴露給window,外部就能夠訪問Game對象了
261  window.Game = Game; 262  }()); 263 
264 
265 
266   //初始化遊戲對象
267   var gm = new Game(document.querySelector(".map")); 268 
269   //初始化遊戲---開始遊戲
270  gm.init(); 271 
272 
273  
274 
275 </script>
276 </body>
277 </html>
View Code

以下圖:單個方塊表示食物,三個方塊鏈接一塊兒表示小蛇,其中紫色方塊是蛇頭,雖然看起來簡單,作起來也須要很多的步驟,咱們先分析一下思路~前端

 

首先,建立一個地圖~而後座標隨機顯示食物方塊,每次食物被小蛇「吃掉」的時候從新初始化;數組

而後,設置固定位置顯示小蛇方塊,設置定時器,讓小蛇動起來,判斷小蛇是否「吃掉」食物,是則初始化食物,複製蛇身最後一個方塊加到小蛇身體最後~判斷小蛇是否「撞牆」,是則提示遊戲提示。app

那麼具體步驟如今開始~dom

設置食物方塊的自調用函數

  • 設置方塊的構造函數,同時設置一個變量準備存儲每一個小方塊食物:
(function () { var elements = []; function Food(x, y, width, height, color) { this.x = x || 0; this.y = y || 0; this.width = width || 20; this.height = height || 20; this.color = color || "green"; }
//把Food暴露給window,外部能夠訪問
window.Food = Food;
}());
  • 初始化食物,賦值而且在地圖上顯示出來,注意:記得把食物加到一開始設置的變量中 var elements = [ ];
Food.prototype.init = function (map) { remove(); var div = document.createElement("div"); map.appendChild(div); div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.backgroundColor = this.color; div.style.position = "absolute"; this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width; this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height; div.style.left = this.x + "px"; div.style.top = this.y + "px"; //把div加入到數組elements中 elements.push(div); };
  • 設置初始化食物的第一個步驟,先在地圖上刪除這個食物:
 function remove() { for (var i = 0; i < elements.length; i++) { var ele = elements[i]; ele.parentNode.removeChild(ele); elements.splice(i, 1); } }

設置小蛇的自調用函數

  • 設置方塊的構造函數,同時設置一個變量準備存儲每一個小蛇的單個身體:
(function () { var elements = []; function Snake(width, height, direction) { this.width = width || 20; this.height = height || 20; this.body = [ {x: 3, y: 2, color: "red"},//頭 {x: 2, y: 2, color: "orange"},//身體 {x: 1, y: 2, color: "orange"}//身體 ]; //方向 this.direction = direction || "right"; }
//把Snake暴露給window,外部能夠訪問
window.Snake = Snake;
}());
  • 設置小蛇初始化的函數
 Snake.prototype.init = function (map) { //先刪除以前的小蛇 remove(); for (var i = 0; i < this.body.length; i++) { var obj = this.body[i]; var div = document.createElement("div"); map.appendChild(div); div.style.position = "absolute"; div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.left = obj.x * this.width + "px"; div.style.top = obj.y * this.height + "px"; div.style.backgroundColor = obj.color //把div加入到elements數組中----目的是爲了刪除 elements.push(div); } };
  • 設置小蛇動起來的函數:
    • 讓小蛇動起來至關因而改變了小蛇的座標
    • 判斷小蛇動起來的方向,而後座標對應處理
    • 判斷小蛇是否「吃到」了食物,是則初始化食物,而且把蛇身最後一個部分複製一分加到蛇身最後
Snake.prototype.move = function (food, map) { //改變小蛇的身體的座標位置 var i = this.body.length - 1;//2 for (; i > 0; i--) { this.body[i].x = this.body[i - 1].x; this.body[i].y = this.body[i - 1].y; } switch (this.direction) { case "right": this.body[0].x += 1; break; case "left": this.body[0].x -= 1; break; case "top": this.body[0].y -= 1; break; case "bottom": this.body[0].y += 1; break; } var headX=this.body[0].x*this.width; var headY=this.body[0].y*this.height; if(headX==food.x&&headY==food.y){ var last=this.body[this.body.length-1]; this.body.push({ x:last.x, y:last.y, color:last.color }); //把食物刪除,從新初始化食物 food.init(map); } };
  • 不要忘記設置初始化小蛇的第一個步驟,在地圖上刪除這個小蛇:
 function remove() { var i = elements.length - 1; for (; i >= 0; i--) { var ele = elements[i]; ele.parentNode.removeChild(ele); elements.splice(i, 1); } }

 

設置遊戲的自調用函數:

  • 設置遊戲的構造函數,同時設置一個變量準備存儲遊戲Game的實例對象:var that=this;
 (function () { var that = null;//該變量的目的就是爲了保存遊戲Game的實例對象------ function Game(map) { this.food = new Food();//食物對象 this.snake = new Snake();//小蛇對象 this.map = map;//地圖 that = this;//保存當前的實例對象到that變量中------此時that就是this } //把Game暴露給window,外部就能夠訪問Game對象了 window.Game = Game; }());
  • 初始化遊戲:能夠設置小蛇和食物顯示出來
 Game.prototype.init = function () { this.food.init(this.map); this.snake.init(this.map); this.runSnake(this.food, this.map); this.bindKey(); };
  • 設置小蛇能夠自動的跑起來
Game.prototype.runSnake = function (food, map) { var timeId = setInterval(function () { this.snake.move(food, map); this.snake.init(map); var maxX = map.offsetWidth / this.snake.width; var maxY = map.offsetHeight / this.snake.height; var headX = this.snake.body[0].x; var headY = this.snake.body[0].y; if (headX < 0 || headX >= maxX) { //撞牆了,中止定時器 clearInterval(timeId); alert("遊戲結束"); } if (headY < 0 || headY >= maxY) { //撞牆了,中止定時器 clearInterval(timeId); alert("遊戲結束"); } }.bind(that), 150); };
  • 設置用戶按鍵,改變小蛇移動的方向
 Game.prototype.bindKey=function () { document.addEventListener("keydown",function (e) { switch (e.keyCode){ case 37:this.snake.direction="left";break; case 38:this.snake.direction="top";break; case 39:this.snake.direction="right";break; case 40:this.snake.direction="bottom";break; } }.bind(that),false); };

初始化遊戲對象,開始遊戲

var gm = new Game(document.querySelector(".map")); gm.init();

好的,到這裏結束啦~ide

另外若是有前端學習者想要尋找夥伴一塊兒合做項目,能夠來我這個羣~羣內還有大神等你哈哈哈~函數

前端學習交流羣 883726280 學習

相關文章
相關標籤/搜索