2012-02-01 30 views
1

我正在爲XNA編寫一個小型遊戲引擎。現在我的實體經理有一個它可以更新和呈現的所有實體的列表。可以說,然而,我想將這個列表分成'子列表'。也許一些實體不需要渲染,因此我們想要將渲染實體與非渲染實體分開,同時保持另一個顯示所有要更新的實體的列表。那就是3個列表。C#列表之間的一致性

有沒有一種方法可以輕鬆地保持列表之間的一致性?確保兩個列表中引用完全相同的對象? (不是該對象的副本?)。在C++中,我們只需要一個指向渲染實體的指針數組,另一個指向不需要的實體。

這個問題並不是真的把實體放入這些列表中,它的處理方式讓我很失望。要摧毀一個實體,我只需在該實體中設置一個'dispose'布爾值爲true。實體管理器在循環遍歷所有實體時,如果'dispose'設置爲true,則刪除對該實體的引用,並且垃圾清理器銷燬實體,因爲沒有更多引用留給它。我是否需要手動檢查與實體有關的每個列表,並從這些列表中刪除該實體以保持事物的一致性?

這個'問題'的另一個例子是四叉樹。我有一個2D遊戲,我爲所有實體生成一個四叉樹。位於2個網格位置之間的實體位於樹的2​​個分支中。我將如何將它從樹上移除?搜索整個樹中對該實體的引用?似乎有點沒有意義,有一個四叉樹,如果是這種情況..!

回答

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 
} 

在這裏,你可以遍歷每個查詢,結果就會從主列表流,並以該列表的所有更新將在查詢結果中反映出來,因爲他們被重複。需要注意的是,在迭代查詢時,列表不能被修改(如添加或刪除)。

+0

這會很慢,如果他們需要經常調用此方法,但不是? – 2012-02-01 03:09:14

+1

@Chris,而不是同時維護3個列表,保持同步,調整大小等?這並不是說性能不是考慮因素,但我希望看到指向Linq查詢的不可接受的性能下降,並證明多列表方法確實更快。 – 2012-02-01 03:13:07

0

至於你的處理問題,你可以實現IDisposable。對於你的列表,你可以創建一個包含兩個列表的類,如果你需要整個列表,實現一個列舉兩個列表的枚舉器。

0

你可以把一個包裝周圍的實體知道列出它是這樣,當你想刪除它,你可以從所有分身相對容易地將其刪除。

0

如果你有多個列表中的項目,那麼是的,如果你想刪除它們,你必須從它們出現的所有列表中刪除它們。一個簡單的方法做,這是去除項目到項目本身分配的責任:例如,渲染項目將在調用RemoveFromLists()他們從繪製的項目列表中刪除自己。

Anthony Pegram描述的查詢的使用消除了這種複雜性,但是如果列表很大,則效率很低,因爲它們不能被逐步更新。對於四叉樹,直截了當的做法是讓每個項目都保留一個它所在的四叉樹節點的列表(或者如果您不想爲項目添加字段,請使用字典)。然後,將它們從所有發生在其中的節點中不斷移出是很簡單的。

0

你可以有你的實體,其暴露在配置之前被解僱了「處置」事件。然後,您可以讓列表的Add方法註冊一個事件處理程序,其中添加的實體將在處理該實體之前從該列表中刪除該實體。