[英]How do I add optional functionality to a class?
I'm currently trying to learn the ins and outs of XNA/C# but I'm currently stuck on a problem: I want to add optional functionality to a class and I have no idea how to even start. 我目前正在尝试学习XNA / C#的细节,但我目前仍然遇到一个问题:我想为一个类添加可选功能,我不知道如何开始。 For clarity, here is my current code:
为清楚起见,这是我目前的代码:
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);
}
}
The logic here is that all Actors have to have a location but they don't necessarily have to have a texture as an Actor could be a light source, trigger, etc etc. Actor2D is similar in this except that it's designated as an Actor that uses 2D texture. 这里的逻辑是所有Actors必须有一个位置,但它们不一定必须有一个纹理,因为Actor可以是光源,触发器等等.Dord2D在此类似,除了它被指定为一个Actor使用2D纹理。 What I want to do is have the ability to add functionality to either of these classes on an as needed basis.
我想要做的是能够根据需要为这些类中的任何一个添加功能。 Say I want the Actor2D to be animated or as mentioned earlier I want to add a trigger or light source to an untextured Actor... What are some ideas that would help me accomplish these goals?
假设我想要动画Actor2D或者如前所述我想为无纹理的Actor添加触发器或光源......有哪些想法可以帮助我实现这些目标?
您可以尝试查看装饰器模式 ,它允许您“粘贴”对象的行为。
If you really want object "morphing" as in objects changing their set of methods at runtime, you're looking at mixins . 如果您真的希望对象“变形”,就像在运行时更改其方法集的对象一样,那么您正在研究mixins 。 (tutorial here )
( 这里的教程)
Fair warning: it is not for the faint hearted. 公平警告:这不是为了胆小的人。
Now since at compile-time you know all the types that will have to be available, use a variety of interfaces: 现在,因为在编译时你知道所有必须可用的类型,所以使用各种接口:
Then provide an implementation for each combination you need. 然后为您需要的每个组合提供实现。 Furthermore, I think it would be best to put all this in your business layer if you have any.
此外,我认为最好将所有这些放在您的业务层中(如果有的话)。
Hope this helps, 希望这可以帮助,
Bab. 巴布。
EDIT: example. 编辑:例子。
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
}
}
Instead of making Actor2D
(and its likes) derived from Actor
. 而不是使
Actor2D
(和它的喜欢)派生自Actor
。 Just change those derived classes to classes of their own, and, have one class (- Actor
) for every "Actor" with all of those properties. 只需将这些派生类更改为自己的类,并为每个具有所有这些属性的“Actor”创建一个类( -
Actor
)。 (An Actor2D
property...) Then use whichever you need at runtime. (
Actor2D
属性......)然后在运行时使用您需要的任何内容。
They will not take up that much resources because they will be pointing to null
's when not used. 他们不会占用那么多资源,因为他们在不使用时会指向
null
。
EDIT: 编辑:
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;
//...
}
And then use it like this: 然后像这样使用它:
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();
//...
So, after a bunch of thinking and searching on Google/StackOverflow. 所以,经过一番思考和搜索Google / StackOverflow之后。 I've finally found my answer.
我终于找到了答案。 Rather than using a traditional OOP approach I learned that I should be using a more Component-Oriented Programming approach.
我没有使用传统的OOP方法,而是学会了使用更加面向组件的编程方法。 I found a really great link at Component based game engine design.
我在基于Component的游戏引擎设计中发现了一个非常棒的链接。
Of particular interest is the 5-part series on T=Machine describing Entity Systems which seems to be an approach which does exactly what I was looking for. 特别感兴趣的是关于T = Machine描述实体系统的5部分系列,它似乎是一种完全符合我要求的方法。 For those interested, the first post is: http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ .
对于那些感兴趣的人,第一篇文章是: 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.