C# 如何向类添加可选功能?
我目前正在尝试学习XNA/C的细节,但我目前遇到了一个问题:我想向类添加可选功能,但我甚至不知道如何开始。为清楚起见,以下是我当前的代码:C# 如何向类添加可选功能?,c#,xna,C#,Xna,我目前正在尝试学习XNA/C的细节,但我目前遇到了一个问题:我想向类添加可选功能,但我甚至不知道如何开始。为清楚起见,以下是我当前的代码: public class Actor { //Fields private Vector3 m_location; //Properties public Vector3 Location { get { return m_location; } set { m_location =
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);
}
}
公共类参与者
{
//田地
专用矢量器3 m_位置;
//性质
公共矢量3位置
{
获取{return m_location;}
设置{m_location=value;}
}
//建设者
公共参与者(浮动x、浮动y、浮动z)
{
位置=新矢量3(x,y,z);
}
公共参与者(矢量3位置)
{
位置=位置;
}
}
公共类Actor 2d:Actor
{
//田地
私有纹理2D m_纹理;
//性质
公共纹理2D纹理
{
获取{return m_texture;}
设置{m_texture=value;}
}
//建设者
公共Actor2D(float x,float y,float z):基(x,y,z){}
公共Actor2D(Vector3向量):基(向量){}
//方法
公共作废抽签(SpriteBatch SpriteBatch)
{
绘制(纹理,新矢量2(Location.X,Location.Y),颜色,白色);
}
公共无效加载(ContentManager内容、字符串资源)
{
纹理=内容。加载(资源);
}
}
这里的逻辑是,所有演员都必须有一个位置,但他们不一定要有纹理,因为演员可以是光源、触发器等。Actor2D在这方面类似,只是它被指定为使用2D纹理的演员。我想做的是能够根据需要向这些类中的任何一个添加功能。假设我想让Actor2D动画化,或者像前面提到的那样,我想给一个无背景的演员添加一个触发器或光源。。。有什么想法可以帮助我实现这些目标?你可以试着看一下,它允许你“附加”对象的行为。如果你真的想让对象“变形”,比如在运行时改变对象的方法集,你可以看看。(教程)
公平警告:这不是给胆小鬼的 现在,由于在编译时您知道所有必须可用的类型,因此可以使用多种接口:
- IHasTexture
- IDrawable:IHasTexture(这意味着IDrawable必须自动实现IHasTexture,因为您无法以其他方式绘制)
- 我可以
- 。。。你要多少就多少
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
}
}
公共接口IMovable{void Move();}
公共类MoveMixin:iMoved
{
public void Move(){Console.WriteLine(“我正在移动”);}
}
公共类SomeDude{}
公共静态类TestClass
{
公共静态测试()
{
var myMixinConfiguration=MixinConfiguration.BuildFromActive()
.ForClass().AddMixin()文件
.BuildConfiguration();
使用(myMixinConfiguration.EnterScope())
{//在此范围内,SomeDude实现了IMovable,但前提是您通过ObjectFactory获得一个实例
var mymovableddude=ObjectFactory.Create(ParamList.Empty);
((IMovable)myMovableDude).Move();//这一行编译和执行得很好,即使类声明没有指定关于Move()的任何内容!!
}
//SomeDude类不再实现iMoved
}
}
而不是使Actor2D
(及其类似内容)派生自Actor
。只需将这些派生类更改为它们自己的类,并为每个具有所有这些属性的“Actor”创建一个类(Actor
)。(一个Actor2D
属性…)然后在运行时使用您需要的任何属性
它们不会占用那么多资源,因为它们在不使用时将指向null
编辑:
然后像这样使用它:
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方法。我在基于组件的游戏引擎设计中发现了一个非常好的链接
特别令人感兴趣的是关于T=Machine的5部分系列,它描述了实体系统,这似乎是一种完全符合我所寻找的方法。对于那些感兴趣的人,第一个帖子是:。谢谢你的快速回答。我很抱歉没有说得那么清楚。我当然希望能够“附加”特性,但我不想使用继承或接口,因为我希望类尽可能基本,每次我想向类添加特定的“功能”时,我都必须重新编译。我真的很想在运行时“抓住”这些特性。谢谢你,宝贝,但我真的在努力避免任何外部库,这仍然不是我想要的(尽管很接近)。我希望事情尽可能干净,我想成为一名演员。我同意所有Actor2D都有“Animate()”方法,但我不希望该方法所需的字段/属性存储在类中,因为这会浪费不必要的资源。mixin允许您定义接口的默认实现,并在运行时动态注入该代码。您的对象仍然可以像它们自己一样强制转换,它们只是获取了一个额外的接口实现。代码完全设置在另一个类(称为“Mixin”)中。在我看来,这就是你想要的。对不起,我试图通读文档和示例,看起来我仍然必须声明say-Actor2D:IAnimated才能定义动画的功能。这很有意义,因为游戏需要知道如何准确地在Actor2D上执行动画。我想我只是不太明白发生了什么
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();
//...