我將如何存儲大量的對象(如子彈或不斷變化的),然後通過它們的索引刪除它們? 我聽說vector :: erase不是很有效率。在C++中存儲大量短命的遊戲對象
回答
使用std::map
(或C++ 11s std::unordered_map
),這些容器對於插入和擦除操作具有更好的分期運行時複雜性。 std::list
也是一個選項(它是顯而易見的選擇,但我首先提到了其他選項,因爲它們還允許在許多遊戲場景中進行快速查找/搜索,這更加重要)。
在更高層次上,您應該閱讀C++容器以及一般運行時複雜性。良好的性能對集裝箱結構的明智選擇至關重要。
'unordered_map'可能更適合如果你經常插入和刪除很多對象。 O(日誌N)插入和刪除時間將會增加。 – Rook 2012-07-10 15:53:04
unordered_set<Bullet*>
會做的很好。那麼你可以簡單地在任何地方使用Bullet*
並忘記索引。最好從一個對象池或類似的東西分配。
或者,由於標準好心搞砸了的界面,你可能需要代替std::unordered_map<Bullet*, std::unique_ptr<Bullet>>
爲更好的異常安全等。
從我極其有限的遊戲引擎編程二手知識中,儘可能避免動態內存分配。因此,unordered_set
或list
將成爲頻繁清除「大量」的主要因素。
編輯:閱讀@詹姆斯甘孜的回答後,我意識到,@交換取出子彈與最後一個元素不起作用,因爲它改變了實彈指數的卡梅倫的建議。我想你不得不使用詹姆斯的建議,或者可能有點向量來標記死亡子彈。
保持項目符號壓縮在一個數組中對於緩存的性能也是很好的。哈希表會緩存好於std::map
的紅黑樹,但是如果您已經通過索引引用了項目符號,爲什麼會產生散列開銷?
如果你確定由它們在向量索引子彈,然後erase
是不是一個好主意;它會改變以下所有元素的索引。子彈由其索引標識的事實在一定程度上限制了您的選擇。在這種情況下,最好的解決方案可能是簡單地將條目標記爲無效,並在稍後重新使用它,或者通過保留無效索引列表(很容易在std::vector
中完成),或者只需在每次要創建新的子彈。如果你有不同類型的子彈(你可能會隨着遊戲的發展),你仍然需要動態分配子彈,並在向量中保留一個指針;空指針對無效是一個很好的選擇。
vector::erase
,因爲它需要將所有包含下列元素,以填補空間,以維護秩序不是很有效。然而,這聽起來像你並不需要保存的順序,在這種情況下,你可以通過在最後用一個替換它,然後丟棄最後一個元素更快速地刪除元素:
std::swap(bullets[index_to_remove], bullets.back());
bullets.pop_back();
(中)着名Alexandrescu考慮短生活動態小對象慢新/免費運營商的主要問題,並建議使用自定義分配器。 std :: map會使用很多這樣的對象(它在內部使用紅黑樹),所以最好使用預分配對象池或std :: map自定義分配器(可能從Alexandresu的Loki庫中獲取一個) )
- 1. 沒有巨大的「常量」類存儲遊戲對象常量
- 2. 數據存儲在遊戲對象
- 3. Android:使用對象來存儲遊戲變量
- 4. 爲遊戲C++高效存儲對象指針
- 5. C中的生命遊戲
- 6. C中的生命遊戲#
- 7. C#2D遊戲中對象的結構
- 8. 存儲大型2D遊戲世界
- 9. 在遊戲世界中存儲和檢索對卸載對象的引用
- 10. C++ - 遊戲引擎中的內存池和對象分配
- 11. 如何存儲2D邊滾動遊戲的屏幕對象?
- 12. HTML5遊戲的對象存儲 - 使用什麼?
- 13. 增量遊戲C#
- 14. 遊戲對象[]在Unity
- 15. 比較遊戲對象增強現實遊戲,團結,Vuforia,C#
- 16. 在TurnBasedMatch中儲存遊戲數據bytearray
- 17. 在C++遊戲中存儲所有實體的最佳方法
- 18. 玩家遊戲對象在遊戲中消失
- 19. 遊戲對象中的相對UILabel
- 20. Libgdx存儲遊戲物品
- 21. Flash遊戲數據存儲
- 22. 遊戲資源存儲
- 23. 遊戲數據存儲
- 24. 競猜對象的遊戲
- 25. 存儲大量數據對象
- 26. Unity 3D:在遊戲對象/記錄路徑背後繪製的遊戲對象?
- 27. 遊戲循環中游戲對象的設計模式
- 28. 在拖放遊戲中匹配對象
- 29. 在Unity中旋轉游戲對象
- 30. 在遊戲中保留對象iphone
使用std :: lists?或者甚至是std :: unordered_map和std :: list的組合,其中映射的關鍵是觸發項目符號或擁有列表中的對象的實體。 – 2012-07-10 15:50:56
你想把每個項目符號存儲爲一個單獨的對象嗎?你爲什麼不把它們作爲一個數量類型存儲?你有多少種不同類型的彈藥? – KRyan 2012-07-10 15:51:34
重新使用對象。把「死」的放在數組的尾部(一個簡單的交換),並跟蹤最後的「實時」項目符號索引。 – Cameron 2012-07-10 15:51:36