1. 程式人生 > >用javascript 面向對象制作坦克大戰(四)

用javascript 面向對象制作坦克大戰(四)

一個 alt 希望 math ava load 初始化 lan 情況

  我們現在還差一個重要的功能,沒錯,敵人坦克的創建以及子彈擊中敵人坦克時的碰撞檢測功能。

5. 創建敵人坦克完成炮彈碰撞檢測

5.1 創建敵人坦克對象

  敵人坦克和玩家坦克一樣,同樣繼承自我們的坦克對象。所以我們在Tank.js中寫入以下代碼:

技術分享 View Code

  然後在我們的遊戲裝載對象初始化遊戲時創建敵人坦克。

技術分享 View Code

5.2 敵人坦克移動和發射炮彈

  坦克創建好了,我們怎麽讓他動起來呢? 很簡單,只需要在我們的遊戲裝載對象中添加一個敵人坦克移動並發射的方法,並且在Run主循環中進行調用就可以了。

代碼:

技術分享 View Code

  ok,現在我們的坦克可以正常的移動和發射炮彈了。但是我們發現坦克移動的方向不會發生改變,所以還需要一個小小的處理,在我們的Mover對象的Move方法中添加以下代碼,敵人坦克就能隨機變換方向了。

1     // 敵人坦克有30%幾率變換方向
2     if ((this instanceof EnimyTank) && Math.random() * 100 > 30) {
3         this.Direction = parseInt(Math.random() * 4);
4     }

5.3 炮彈碰撞檢測

  之前我們炮彈的碰撞檢測只寫了打到障礙物的檢測,所以我們還需要添加炮彈碰撞到坦克的情況。 實現思路很簡單,當我們的子彈穿過空地或草地(坦克能停留的兩種地形)時,我們檢測地圖的占有對象是不是坦克就可以了。上代碼:

Bomb.js:

技術分享 View Code

  此時,我們會發現當玩家的炮彈擊中敵人後,敵人坦克會隨機的占有他的4個方向中的一個單元格。這是什麽原因造成的呢? 我們可以想想,當我們的炮彈命中敵人的時候,他有可能正在移動。這時候我們把他移除了,但是他的Move的步進方法還會繼續執行,別忘了,我們是用的setInterval,所以他就鬼使神差步進到下一個單元格。 這時候坦克對象移除了,但是占用還在,就會出問題了。

  解決的方案很簡單,我們在移除坦克時將坦克的UI 已經設置為null了,所以在步進前我們判斷他UI的值為null時,我們就停止步進就ok了。代碼很簡單:

技術分享
1   if (This instanceof EnimyTank) {
2             // 如果敵人坦克被銷毀,則停止步進
3             if (This.UI == null) {
4                 clearInterval(subMove);
5             }
6         }
技術分享

5.4 多個敵人坦克的解決方案

  這時候我們還發現一個嚴重的問題: 我們的敵人坦克是保存在遊戲裝載對象裏的一個數組,當我們消滅敵人坦克時,我們不知道到底該從中移除哪個坦克。

  其實這個問題的解決思路相當簡單:在初始化敵人坦克時給他一個屬性保存他在數組中的索引,當需要消除坦克對象時,我們直接根據索引移除就可以了。

1、初始化存儲索引

  

 enimyT1.index = this._enimyTanks.length;

2、給Array擴展原型方法,移除指定位置的數組。

  

技術分享
 1 Array.prototype.removeAt = function (index) {
 2     var arr = [], j = 0;
 3     // 遍歷數組,過濾指定位置的元素
 4     for (var i = 0; i < this.length; i++) {
 5         if (i != index) {
 6             arr[j++] = this[i];
 7         }
 8     }
 9     return arr;
10 }
技術分享

3、修改炮彈打中敵人的代碼。

技術分享
 1  // 玩家炮彈打中敵人坦克
 2             if (nextObj.occupier instanceof EnimyTank && this.Owner instanceof SelfTank) {
 3                 UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap"));
 4                 nextObj.occupier.UI = null;
 5                 var arr = GameLoader.prototype._enimyTanks.removeAt(nextObj.occupier.index);
 6                 // 重置坦克索引
 7                 for (var i = 0; i < arr.length; i++) {
 8                     arr[i].index = i;
 9                 }
10                 GameLoader.prototype._enimyTanks = arr;
11                 nextObj.occupier = null;
12             } 
技術分享

  這裏有一個重置索引的代碼,大家可能不明白為什麽這麽做。 當我們移除掉一個坦克後,數組的元素個數變了,所以原來的數組索引有可能失效。所以我們只要重置一下,就ok了。

  大致的功能已經出來了,肯定有一些bug和待完善的地方。列如坦克的移動和炮彈的發射不兼容,玩家子彈和敵人子彈碰撞時應該消除... 還有一些功能未實現:玩家坦克被擊中消失、遊戲道具、敵人坦克生成、計分、關卡、玩家自己繪制地圖。 沒有錯,我打算把這些難題交給大家了。 寫這個博客主要的目的已經達到了:學習js面向對象。希望大家有時間繼續完善這個遊戲,在完成的過程中可以學到很多東西。 感謝各位聽我啰嗦。

最後這個版本的下載地址:

http://pan.baidu.com/s/1pJ3DWKV

  

用javascript 面向對象制作坦克大戰(四)