2014-09-01 56 views
5

我正在製作一個開放世界的單人RPG遊戲,其中世界由大部分隔離區域組成,其中可擴展性分爲多個部分。世界包含彼此相互作用的生物。大多數生物都會參考其他生物,可能包括其他地區的生物。爲being類定義可能看起來像在遊戲世界中存儲和檢索對卸載對象的引用

class Being { 
    weak_ptr<Being> target; 
    // other members 
}; 

當然,我需要能夠保存和載入遊戲狀態,並從磁盤。現在,我不想讓所有的生物隨時加載。我只想加載玩家附近的生物,或者最壞的情況下加載當前加載區域中的所有生物。完成這個任務的好策略是什麼?以下是我迄今爲止討論的幾個想法。

  1. 在磁盤上,存儲將爲每個被引用的存儲存儲唯一的標識符。當A被加載時,如果已經加載了被引用的B,則指針被簡單地設置。如果B被卸載,它也必須被加載。缺點是這可能會遞歸加載很多可能不會被直接使用的生命。
  2. 而不是包含實際指針的生物,他們將包含標識符。然後當被引用的生物被使用時(例如,如果一個生物需要傷害另一個生物),它們將只在需要的時候加載。這使得引用變得複雜,並且有可能導致更多的保存/加載操作,但它避免了加載不必要的數據。

是否有更好的選擇這些選項?我想這是一個常見問題,但我一直沒能找到有關SO的相關問題。

+0

你的方法實際上是緩存對象。你可以看看這裏:http://stackoverflow.com/questions/17807805/how-to-cache-1000s-of-large-c-objects主要問題是如何使它有效地找到要加載的對象,因爲這取決於他們的位置,而不是他們的ID。 – Christophe 2014-09-01 17:25:19

回答

1

你可以使用像Flyweight Pattern這樣的東西來幫助你做到這一點。然後,每種類型的存儲實際上只加載一次(可以根據需要懶惰地完成),然後每個存儲實例只包含特定於實例的變量,例如位置,速度等。

如果這還不夠的節省,你可以編寫一個實例管理器,該管理器具有一個用於請求一個引用計數指針的API。引用對象會在實例管理器被破壞時通知實例管理器。這將使參考管理器可以根據需要輕鬆地將Beings調入和調出磁盤。

+0

不幸的是,我不認爲享元模式會給我多少儲蓄,因爲生命中主要包含「外在」數據(比如長長的統計數據,庫存等)。第二種方法聽起來很有趣。這與我的想法沒有關係嗎? 2?如果沒有,你能否將我與這種方法的一個例子聯繫起來?謝謝! – 2014-09-08 21:15:50