2013-10-10 27 views
1

我有一個實體組件系統,可以讓我在運行時創建自定義實體並組裝它們的功能。該過程包括製作新的實體實例,然後向其添加組件實例。缺點是現在每次我想修改我需要做的對象的X座標,這是醜陋的。隱藏組件系統的冗長性並以通用的方式爲用戶提供更優雅的界面

我當然可以創建一個擴展實體並添加了一些固定組件的類,然後爲這些組件添加屬性形式的簡寫,這樣當我想更改X座標時,我只需要做obj.Transform.X。如果沒有更好的解決方案,這將是我的選擇,但是,如果有一種將這些簡寫添加到實體的任何子類的通用方法,我會更喜歡它。例如,我可以創建一個名爲ITransformable的接口來定義Transform屬性,但是每個類都必須包含相同的冗餘屬性實現。

我考慮的另一個選擇是有接口,但只能將它們用作擴展方法的標記。然後,我可以在ITransformable上實現一個名爲Transform()的方法作爲擴展方法,以獲取正確的組件。問題在於我無法將接口限制爲僅實體類,因此我無法訪問我的擴展方法中的GetComponent方法,並且Transform().X仍然看起來非常難看。我可以做一些類型的投射,但是這會嚴重地變成黑客。

有沒有其他理智的選擇呢?

回答

2

我今年寫了這個早期的解決方案:ComponentsComponentEntities

組件之間的關係是通過註解屬性和方法定義,如所見here

// Link to component of type B through a property. 
// The name doesn't matter. 
[ComponentLink] 
B B { get; set; } 

// Called when components are added or removed. 
// The parameter type acts as a filter. 
[NotifyComponentLinked] 
void Added(object o) 
{ Console.WriteLine(this.GetType().Name + " linked to " + o.GetType().Name + "."); } 
[NotifyComponentUnlinked] 
void Removed(object o) 
{ Console.WriteLine(this.GetType().Name + " unlinked from " + o.GetType().Name + "."); } 

// Attaches to events in compenents of type D and E. 
// Rewriting this with Lambda Expressions may be possible, 
// but probably would be less concise due to lack of generic attributes. 
// 
// It should be possible to validate them automatically somehow, though. 
[EventLink(typeof(D), "NumberEvent")] 
[EventLink(typeof(E), "NumberEvent")] 
void NumberEventHandler(int number) 
{ Console.WriteLine("Number received by F: " + number); } 

ComponentEntities項目包含集合,這些集合將自己添加爲自己或添加到其中的實體的組件,以避免全局單例。如果你想要一個帶有Components和ComponentsTest(用法示例)項目的VS解決方案,請克隆bundle repository

組件的許可證是LGPL,目前爲止我沒有授權使用ComponentEntities(我剛剛將存儲庫設置爲公共),但是如果您需要,您可以在大約10分鐘內寫出與我上面所寫內容相同的內容。

0

你也許可以用DynamicObject做這樣的事情。

http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

下面是一個例子:

using System; 
using System.Collections.Generic; 
using System.Dynamic; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic ent = new Entity(); 
     ent.Components.Add(new Transform() { X = 5, Y = 8 }); 

     Console.WriteLine(ent.Transform.X); 
     ent.Transform.X = 12; 
     Console.WriteLine(ent.Transform.X); 
     Console.ReadKey(); 
    } 
} 

class Entity : DynamicObject 
{ 
    public List<Component> Components = new List<Component>(); 

    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     for (int i = 0; i < Components.Count; i++) 
     { 
      Component component = Components[i]; 
      if (component.GetType().Name == binder.Name) 
      { 
       result = component; 
       return true; 
      } 
     } 

     result = null; 
     return false; 
    } 
} 

class Component 
{ 

} 

class Transform : Component 
{ 
    public float X; 
    public float Y; 
} 
+0

請嘗試閱讀本文http://stackoverflow.com/help/deleted-answers,以獲得更多瞭解如何**不**回答。即:「不能從根本上回答問題的答案」:**僅僅是一個鏈接到外部網站** –

相關問題