2014-03-02 85 views
2

因此,我試圖將一個組件系統放在我的框架中的gameobjects中,並且我希望能夠將所有組件存儲在一個數組中(或map ... et。 ),所以它們都可以很容易地更新,並且這些類不需要爲組件預定義的插槽,所以我創建了一個基本組件類,並創建了一個類型組件映射,然後讓其他組件擴展組件,如果我只想在所有這些組件上調用更新方法,它就能正常工作,但我希望它們都能夠擁有他們想要的任何方法。當然,這是行不通的,因爲編譯器不知道每個組件可能是什麼類。然後我發現我可以通過使用類似這樣的東西(如果我知道它的類型)將組件轉換爲它自己的類型:return cast(components.get("transform"), TransformComponent); 然後訪問孩子的功能。這是一種好的做事方式,或者是一個可怕的設計決定,我應該修改組件的整個結構? 對不起,如果這是一個非常缺乏經驗的問題,謝謝, 尼科將父類轉換爲子類

(注意:我使用haXe的,但我相信這適用於所有OOP語言)

回答

2

我個人認爲這是好的,只要因爲你完全確定你正在鑄造到正確的類型 - 我見過其他一些Haxe庫(如minject)使用這種方法。

隨着HAXE,您可以使用類型參數,如下所示:

var c:Map<String,BaseComponent>; 

public function getComponent<T:BaseComponent>(name:String, type:Class<T>):T { 
    if (components.exists(name)) { 
     var c = components[name]; 
     if (Std.is(c, type)) { 
      return cast c; 
     } 
    } 
    return null; // the component with that name didn't exist, or was the wrong type 
} 

這樣您的使用情況可以是:

var transform = componentManager.getComponent("transform", TransformComponent); 
if (transform!=null) { 
    transform.doSomething(); 
} 

在這種情況下,轉換將全部輸入爲「TransformComponent」編譯器會讓你訪問它的所有方法等。

最後,如果你只有一個組件的每個類型的實例,你可以更容易:

public function addComponent<T:BaseComponent>(component:T) { 
    var type = Type.getClass(component); 
    var name = Type.getClassName(type); 
    components[name] = component; 
} 

public function getComponent<T:BaseComponent>(type:Class<T>):T { 
    var name = Type.getClassName(type); 
    return cast components[name]; // Either the component with the correct type name, or null. 
} 

componentManager.addComponent(new TransformComponent()); 
var t = componentManager.get(TransformComponent); 
$type(t); // TransformComponent, it is correctly typed 
+0

真棒:)多數民衆贊成正是我想知道,和仿製藥使它更清潔...謝謝 – Nico

+0

我想我會把這兩種方法爲方便 – Nico

+0

只是讓我明白這一點完全地,如果沒有第二個參數或指定的類型,投射如何工作,例如,我可以理解:var i:Int =投射myfloat,但它如何在沒有指定類型的情況下工作? – Nico