簡體   English   中英

如何向類中添加可選功能?

[英]How do I add optional functionality to a class?

我目前正在嘗試學習XNA / C#的細節,但我目前仍然遇到一個問題:我想為一個類添加可選功能,我不知道如何開始。 為清楚起見,這是我目前的代碼:

public class Actor
{
    //Fields
    private Vector3 m_location;

    //Properties
    public Vector3 Location
    {
        get { return m_location; }
        set { m_location = value; }
    }

    //Constructors
    public Actor(float x, float y, float z)
    {
        Location = new Vector3(x, y, z);
    }
    public Actor(Vector3 location)
    {
        Location = location;
    }
}

public class Actor2D : Actor
{
    //Fields
    private Texture2D m_texture;

    //Properties
    public Texture2D Texture
    {
        get { return m_texture; }
        set { m_texture = value; }
    }

    //Constructors
    public Actor2D(float x, float y, float z) : base(x, y, z) {}
    public Actor2D(Vector3 vector) : base(vector) {}

    //Methods
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(Texture, new Vector2(Location.X, Location.Y), Color.White);
    }
    public void Load(ContentManager content, string asset)
    {
        Texture = content.Load<Texture2D>(asset);
    }
}

這里的邏輯是所有Actors必須有一個位置,但它們不一定必須有一個紋理,因為Actor可以是光源,觸發器等等.Dord2D在此類似,除了它被指定為一個Actor使用2D紋理。 我想要做的是能夠根據需要為這些類中的任何一個添加功能。 假設我想要動畫Actor2D或者如前所述我想為無紋理的Actor添加觸發器或光源......有哪些想法可以幫助我實現這些目標?

您可以嘗試查看裝飾器模式 ,它允許您“粘貼”對象的行為。

如果您真的希望對象“變形”,就像在運行時更改其方法集的對象一樣,那么您正在研究mixins 這里的教程)
公平警告:這不是為了膽小的人。

現在,因為在編譯時你知道所有必須可用的類型,所以使用各種接口:

  • IHasTexture
  • IDrawable:IHasTexture(這意味着IDrawable會自動實現IHasTexture,因為你無法繪制)
  • ILoadable
  • ......盡可能多的你想要的。

然后為您需要的每個組合提供實現。 此外,我認為最好將所有這些放在您的業務層中(如果有的話)。

希望這可以幫助,

巴布。

編輯:例子。

public interface IMovable { void Move(); }

public class MoveMixin : IMovable
{
   public void Move() { Console.WriteLine("I am moving"); }
}

public class SomeDude { }

public static class TestClass
{
   public static Test()
   {
      var myMixinConfiguration = MixinConfiguration.BuildFromActive()
           .ForClass<SomeDude>().AddMixin<MoveMixin>()
           .BuildConfiguration();
      using(myMixinConfiguration.EnterScope())
      {//In this scope, SomeDude implements IMovable, but only if you get an instance through the ObjectFactory
         var myMovableDude = ObjectFactory.Create<SomeDude>(ParamList.Empty);
         ((IMovable)myMovableDude).Move(); //This line compiles and executes just fine, even though the class declaration does not specify anything about Move() !!
      }
      //The SomeDude class no longer implements IMovable
   }
}

而不是使Actor2D (和它的喜歡)派生自Actor 只需將這些派生類更改為自己的類,並為每個具有所有這些屬性的“Actor”創建一個類( - Actor )。 Actor2D屬性......)然后在運行時使用您需要的任何內容。

他們不會占用那么多資源,因為他們在不使用時會指向null

編輯:

class Actor
{
    public Stuff2D stuff2d = new Stuff2D();
    public StuffLightPower lightPower = new StuffLightPower();
    //...
}

class Stuff2D
{
    public int height;
    public int weight;
    //...
}

class StuffLightPower
{
    public int lumen;
    public Color color;
    //...
}

然后像這樣使用它:

Actor actor1 = new Actor();

//First it's going to be a 2D.
actor1.stuff2d.weight = 3;
//...

//Now it's changed to a light source.
actor1.stuff2d = null;
actor1.lightPower.color = Color.White;
//...

//And back again.
actor1.lightPower = null;
actor1.stuff2d = new Stuff2D();
//...

所以,經過一番思考和搜索Google / StackOverflow之后。 我終於找到了答案。 我沒有使用傳統的OOP方法,而是學會了使用更加面向組件的編程方法。 我在基於Component的游戲引擎設計中發現了一個非常棒的鏈接。

特別感興趣的是關於T = Machine描述實體系統的5部分系列,它似乎是一種完全符合我要求的方法。 對於那些感興趣的人,第一篇文章是: http//t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM