我正在为XNA编写一个小型游戏引擎。现在我的实体经理有一个可以更新和呈现的所有实体的列表。但是,让我们说,我希望将此列表拆分为“子列表”。也许某些实体不需要渲染,因此我们希望将渲染实体与非渲染实体分开,同时维护另一个显示所有实体以进行更新的列表。这就是3个列表。
有没有办法轻松维护列表之间的一致性?要确保在两个列表中引用完全相同的对象? (不是对象的副本?)。在C ++中,我们只有一个指向渲染实体的指针数组,另一个指向实体的指针数组。
问题并不是真正将实体放入这些列表中,而是将它们处理掉了。为了摧毁一个实体,我只是在该实体中将'dispose'布尔设置为true。当循环遍历所有实体时,实体管理器在'dispose'设置为true时删除对该实体的引用,并且垃圾清理器销毁实体,因为没有更多的引用留给它。我是否必须手动浏览与实体有关的每个列表,并从这些列表中删除该实体以保持一致?
这个'问题'的另一个例子是四叉树。我有一个2D游戏,我为所有实体生成一个四叉树。位于2个网格位置之间的实体位于树的2个分支中。我将如何从树上删除它?在整个树中搜索对该实体的引用?如果是这样的话,有一个四叉树似乎有点无意义..!
答案 0 :(得分:3)
考虑而不是3个列表,有一个列表和2个该列表的查询。
var list = GetYourMainList();
var renderableEntities = list.Where(item => item.IsRenderable);
var nonrenderableEntities = list.Where(item => !item.IsRenderable);
// work with the queries
foreach (var item in renderableEntities)
{
// do whatever
}
在这里,您可以迭代每个查询,结果将从主列表中流出,并且对该列表的任何更新将在迭代时反映在查询结果中。需要注意的是,在迭代查询时,无法修改列表(如添加或删除)。
答案 1 :(得分:0)
关于您的处置问题,您可以实施IDisposable
。对于您的列表,您可以创建一个包含两个列表的类,如果您需要整个列表,请实现一个枚举器,该枚举器将枚举这两个列表。
答案 2 :(得分:0)
您可以在实体周围放置一个包装器,知道它所在的列表,这样当您想要删除它时,您可以相对轻松地从所有位置将其删除。
答案 3 :(得分:0)
如果您有多个列表中的项目,那么是,如果要删除它们,则必须将它们从发生它们的所有列表中删除。执行此操作的一种简单方法是将项目移除项目的责任分配给项目:例如,当您在项目上调用RemoveFromLists()时,渲染项目将从渲染项目列表中删除。
Anthony Pegram所描述的查询的使用消除了这种复杂性,但如果列表很大,则效率很低,因为它们无法逐步更新。
对于四叉树,一个简单的事情就是让每个项目都保留一个四叉树节点列表(或者如果你不想在你的项目中添加一个字段,请使用一个字典)。然后,可以很容易地将它们从恒定时间内发生的所有节点中删除。
答案 4 :(得分:0)
您可以让您的实体公开在处置之前触发的“Disposing”事件。然后你可以让你的列表的Add方法注册一个事件处理程序,其中添加的实体将在处理之前从列表中删除该实体。