我目前正在尝试学习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在此类似,除了它被指定为使用2D纹理的Actor。我想要做的是能够根据需要为这些类中的任何一个添加功能。假设我想让Actor2D动画或者如前所述我想为无纹理的Actor添加触发器或光源......有哪些想法可以帮助我实现这些目标?
答案 0 :(得分:3)
您可以尝试查看decorator pattern,它可以让您“对待”对象的行为。
答案 1 :(得分:1)
如果你真的想要对象&#34;变形&#34;就像在运行时更改其方法集的对象一样,您需要查看mixins。 (教程here)
公平警告:这不适合胆小的人。
现在,在编译时你知道所有必须可用的类型,使用各种接口:
然后为您需要的每个组合提供实现。此外,我认为最好将所有这些放在您的业务层中(如果有的话)。
希望这有帮助,
巴布。
编辑:示例。
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
}
}
答案 2 :(得分:1)
而不是从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();
//...
答案 3 :(得分:1)
所以,经过一番思考和搜索Google / StackOverflow之后。我终于找到了答案。我没有使用传统的OOP方法,而是学会了使用更加面向组件的编程方法。我在基于组件的游戏引擎设计中发现了一个非常棒的链接。
特别感兴趣的是关于T = Machine描述实体系统的5部分系列,它似乎是一种完全符合我要求的方法。对于有兴趣的人,第一篇文章是:http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/。