游戏项目类层次结构的建议
我正在编写一个 MUD 引擎,并且刚刚开始研究游戏对象模型,它需要可扩展。
我需要帮助主要是因为我所做的事情感觉很混乱,但我想不出另一个更有效的解决方案。
我有一个名为 MudObject
的类,另一个名为 Container
的类,一个容器可以包含多个 MudObjects
,但它是一个 MudObject
code> 本身,但是 MudObject
需要知道它们包含在什么中。
所以它们看起来像这样:
public abstract class MudObject
{
Container containedBy;
}
public abstract class Container : MudObject
{
List<MudObject> Contains;
}
(请注意这些只是示例以及一些限定符和访问修饰符、属性等错过了)
现在,这本身看起来很混乱,但让我们添加一些其他内容:
Item
是一个 MudObject
,所有视觉项目(例如武器)将被继承,但是其中一些也需要是容器(例如箱子)。 但是c#中没有多重继承,所以它归结为接口,最好的选择是让容器成为一个接口(据我所知)但是有一个我不希望它成为接口的原因,也就是说,将 MudObject
添加到容器将导致容器更新 MudObject
的 .containedBy
值。
有什么想法可以让这项工作成功,还是我陷入了让事情变得太复杂的陷阱?
如果是这样,您还有什么建议?
I'm writing a MUD engine and I've just started on the game object model, which needs to be extensible.
I need help mainly because what I've done feels messy, but I can't think of a another solution that works better.
I have a class called MudObject
, and another class called Container
, A container can contain multiple MudObjects
, but is a MudObject
itself, however MudObject
s need to know what they are contained in.
So they look something like this:
public abstract class MudObject
{
Container containedBy;
}
public abstract class Container : MudObject
{
List<MudObject> Contains;
}
(please note these are just example and some qualifiers and access modifiers, properties and such are missed off)
Now just this in itself seems messy, but lets add something else to the mix:
Item
is a MudObject
that all visual items (such as weapons) will be inherited from, however some of these need to be containers too (like chests). But theres no such as multiple inheritance in c#, So it comes down to interfaces, the best choice would be to make the container an interface (as far as I can see) However there was a reason I didn't want it to be, that being that adding an MudObject
to a container will cause the container to update the MudObject
s .containedBy
value.
Any ideas that would make this work, or am I falling into the trap of making things too complicated?
If so what else could you suggest?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我认为你过于复杂化了。 如果 MudObjects 可以包含其他 MudObjects,则您需要的单个基类应该遵循以下原则:
这类似于 WinForms 和 ASP.NET 的工作方式。 许多容器控件都是控件,并且可以包含子控件的集合。
I think you are overcomplicating. If MudObjects can contain other MudObjects, the single base class you need should be along these lines:
This is similar to the way WinForms and ASP.NET works. Many container controls are both controls, and can contain a collection of subcontrols.
您的要求是合理的,并且是 复合设计模式
What you're asking for is reasonable, and is the Composite Design Pattern
您想要的非常合理:它与 Windows 窗体控件没有什么不同,Windows 窗体控件本身可以是其他控件的容器。
您需要做的是创建自己的
List
实现:除其他外,它实现了添加功能:
注意:此方法会隐藏而不是覆盖旧的方法添加功能
通过这种方式,您可以在添加时立即填充 ContainedBy 属性。 当然,这意味着您的 ContainedBy 可以为
null
,这意味着它是顶级对象。最后,我认为没有必要创建单独的
MudObject
和Container
类,因为容器看起来是MudObject
所固有的( ff 使用 C# 3.0 自动属性):What you want is quite reasonable: it's no different from Windows form controls, which can itself be a container of other controls.
What you do need to do is create your own implementation of
List<MudObject>
:which implements, among other things, the add functionality:
Note: this method shadows, instead of overrides, the old Add functionality
In this way you immediately populate the ContainedBy attribute upon adding. Of course it's implied that your ContainedBy can be
null
, which means that it is the top level object.Finally, I don't think there's a need to make separate
MudObject
andContainer
classes, since being a container looks intrinsic to aMudObject
(the ff uses C# 3.0 automatic properties):为什么不制作所有 MudObjects 容器? ...或者至少,就您的类代码而言,能够包含其他对象。 例如,
您可以在对象本身上设置某种标志,以识别玩家是否能够实际将东西放入或取出对象本身,而不是使用对象的类型来弄清楚。
Why not make all MudObjects containers? ...or at least, have the ability to contain other objects, in terms of your class code. E.g.
You can then set some sort of flag on the object itself to identify whether the players are able to actually put things into or out of the object themselves, rather than using the type of the object to figure it out.
实际上,让某个东西既是项目又是容器是一个坏主意。 这打破了许多对 IList 做出假设的绑定场景; 因此,对于一个箱子,我可能会想在作为集合的箱子上拥有一个 Items 属性,但让箱子只是一个箱子。
然而,对于所提出的问题...
我很想将 MudObject 作为接口...这样,您可以使用类似以下的内容,它为您提供了任何具体对象的通用容器,以及自动父子关系:
Actually, it is a bad idea for something to be both an item and a container. This breaks a number of binding scenarios that make assumptions about IList; so for a chest, I might be tempted to have an Items property on the chest that is the collection, but let the chest just be a chest.
However, for the question as asked...
I would be tempted to make the MudObject the interface... that way, you can use something like the following, which gives you a generic container of any concrete objects, along with automatic parenting:
采用组合而不是继承的想法似乎已经消失了。
也许我可以做更多这样的事情
Going with the idea of composition over inheritance answer which seems to have vanished.
Perhaps I could do something more like this
按照 Marc 的回答,编写几个在幕后维护双向父子关系的类。
Along the lines of Marc's answer, write a couple of classes that maintain a bidirectional parent-child relationship under the hood.