2013-01-04 39 views
0

我想提出一個太空入侵者一種基於ActionScript3比賽,我已經創建了從舞臺中刪除子彈的方法一種方法:去除不同類型的對象從AS3的階段,只用

private function removeBullet(bb:Bullet = null):void { 

    var leng:uint = bulletVector.length; 
    if (bb) 
    { 
     for (var i:uint = 0; i < leng; i++) 
     { 
      if (bulletVector[i] == bb) 
      { 
       bulletVector.splice(i, 1); 
       break; 
      }     
     } 

     // Remove bullet from the Display List 
     removeChild(bb); 

     // Return the bullet to its object pool 
     bulletPool.returnObject(bb);  

    } else { 

     // Remove all existing bullets currently on screen 
     for (var j:uint = 0; j < leng; j++) 
     { 
      var bullet:Bullet = bulletVector[j]; 
      removeChild(bullet); 
      bulletPool.returnObject(bullet); 
     } 
     bulletVector.splice(0, leng); 
    } 
} 

bulletVector是一個Vector,它包含當前顯示的所有項目符號,並且bulletPool是一個對象池類,用於在項目不再使用時返回項目符號。如果沒有參數傳遞給該方法,該方法將刪除屏幕上的所有項目符號。

現在,我有一個相同方法從屏幕上刪除敵人:

private function removeEnemy(ee:Enemy = null):void { 

    var leng:uint = enemyVector.length; 
    if (ee) 
    { 
     for (var i:uint = 0; i < leng; i++) 
     { 
      if (enemyVector[i] == ee) 
      { 
       enemyVector.splice(i, 1); 
       break; 
      }    
     } 

     // Remove enemy from the Display List 
     removeChild(ee); 

     // Return the enemy to its object pool 
     enemyPool.returnObject(ee); 

    } else { 

     // Remove all existing enemies currently on screen 
     for (var j:uint = 0; j < leng; j++) 
     { 
      var enemy:Enemy = enemyVector[j]; 
      removeChild(enemy); 
      enemyPool.returnObject(enemy); 
     } 
     enemyVector.splice(0, leng);  
    } 
} 

兩個「子彈」和「敵人」是擴展Sprite類的類。我的問題是:是否可以將這兩種方法合併爲一個處理子彈和敵人的方法,具體取決於哪一個作爲參數傳遞?

[編輯] 我心目中什麼是這樣的:(僞)

if (ee is Bullet) 
{ 
    var s:String = "bullet" 
} else if (ee is Enemy) 
{ 
    var s:String = "enemy" 
} 

eval[s+"Vector"].splice(i, 1); 
eval[s+"Pool"].returnObject(ee); 

[/編輯]

換句話說,有沒有語法,允許訪問的載體和/或類(對象池),而不必將其名稱硬編碼到方法中?

在此先感謝您的幫助。

回答

3

像這樣的事情可能爲你工作...

private function removeItem(ee:* = null):void { 

if (ee) { 
//ee has a value 

if (ee is Bullet) { 
//remove bullet 

} else if (ee is Enemy) { 
//remove Enemy 

} 

} else { 

//ee is null so remove all bullets and emenies 

} 
} 
+0

其實這比我建議的要聰明得多。只有在添加新類型時需要編輯該方法。 – JulianG

+0

當ee爲空時,你不知道你是否想要移除所有的子彈或所有的敵人。 我建議有一個單獨的removeAll方法,因爲它會更安全。 – JulianG

+0

現在我想起它......執行//刪除敵人和/刪除子彈會是什麼樣子?我想他們會兩個幾乎相同的代碼塊... – JulianG

1

簡短的回答:使用數組而不是向量的敵人和子彈名單。

創建3個參數的方法,包括:列表:數組和一個項目:雪碧和游泳池:數組然後從指定的數組中刪除該項目,而不是「硬編碼」的實例,並用兩個相同的結束了方法。

/** 
* Removes item from specified list 
* @param list 
* @param item 
*/ 
public function removeItem(list:Array, item:Sprite, pool:Array):void 
{ 
    // implement here 
} 

龍答:

它,因爲你使用的載體是棘手。

我的第一個念頭是創建一個通用的功能,服用2個參數,列表和項目:(讓我們忽略池現在)

/** 
* Removes item from specified list 
* @param list 
* @param item 
*/ 
public function removeItem(list:Vector.<Sprite>, item:Sprite):void 
{ 
    // implement here 
} 

,但我想你的子彈的名單類型向量。而你的列表敵人是Vector類型的,對嗎?

所以即使兩個子彈和敵人的擴展雪碧,如果你打電話給使用Vector實例這種方法,例如:

var list:Vector.<Bullet>; 
var item:Bullet; // extends Sprite 
removeItem(list, item); 

這不會編譯。你會得到:

Error: Implicit coercion of a value of type __AS3__.vec:Vector.<Bullet> to an unrelated type __AS3__.vec:Vector.<flash.display:Sprite>. 

在一個單獨的說明

你RemoveItem方法似乎是在做兩件事情。刪除指定的項目和/或刪除所有項目。爲了安全和清晰,我會保持這些分開。每種方法只應執行一件事。

此外,使用此設置,如果在運行時您對某個項目的引用意外爲空,則最終將從列表中刪除所有項目。可能不是你想要的。

我將宣佈兩項功能:

function removeItem(...) 

function removeAllItems(...) 
+0

感謝Julian的回答,是的,你是正確的將拆分方法分爲兩種不同的方法,事實上,其他方法略有不同,刪除其他類型遊戲中的對象確實具有「一個」和「所有」對象的單獨功能。所以這絕對是我必須做的事情。 – Francesco

0

關於第二個想法,我現在將有利於軟打字比使用數組,因爲它不會強迫你改變你的應用程序的其餘部分(例如,你可以保持你的向量)

public function removeItem(list:*, pool:ObjectPool, item:Sprite):void 
{ 
    // remove item from specified list 
    var indx:int = list.indexOf(item); 
    if (indx >= 0) 
    { 
     list.splice(indx, 1); 
    } 
    // remove display object from display list 
    if (this.contains(item)) 
    { 
     this.removeChild(item); 
    }   
    // return itemitem to specified pool 
    pool.returnObject(item); 
} 

注意你如何不需要迭代矢量來找出刪除(拼接)哪個索引。您可以改用indexOf方法。

+0

在我的例子中,所有池都是ObjectPool類的實例或繼承,我假設有一個returnObject方法,對吧? – JulianG

+0

是的,objectPool是一個類(這個類:[link](http://help.adobe.com/en_US/as3/mobile/WS948100b6829bd5a6-19cd3c2412513c24bce-8000.html))。 我喜歡你發佈的解決方案,非常優雅。我看到它的方式,@ crooksy88發佈的解決方案的優點是我可以只傳遞一個參數給方法,而且方法調用本身看起來比較整潔(即remove(bullet)),而不是remove(bullerVector,bulletPool,bullet )),而您的解決方案的優點是方法中的實際代碼更短且統一 - 因此更容易維護。再次感謝! – Francesco