繁体   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