2012-03-01 37 views
0

因此,我用C++設計了一個具有大量數據的2D遊戲 - 基本上,它具有隨機生成的塊狀地形(以非常大的字節數組形式),很多Terraria的風格,並且還需要爲怪物(其他各種遊戲對象)保存狀態。隨着玩家四處奔跑,遊戲世界的各個部分將被加載/保存到磁盤中,從而形成一個無限擴展的遊戲世界(類似於Minecraft)。爲遊戲節省一噸數據

將所有內容保存到磁盤的最佳選擇是什麼?我最關心的是效率(因此用戶不必等待內容加載),但易用性和可維護性緊隨其後。我對Minecraft的保存方法非常熟悉,對每個「塊」都有一個單獨的文件,但我想知道 - 我應該指定我自己的文件,如Minecraft還是使用數據庫?還有什麼其他的可能性?如果我使用一個文件,通過向操作系統請求原始訪問並處理自己(如同數據庫一樣),我可以獲得顯着的性能提升嗎?

此外,我希望能夠將項目從PC移植到Mac和控制檯 - 各個平臺的替代方案都很好,我只需根據平臺交換方法。

謝謝!

+2

這可能是[gamedev.se](http://gamedev.stackexchange.com/)更好的問題。 – 2012-03-01 04:34:16

回答

1

單個文件會比依靠文件系統組織更簡單,佔用更少的物理磁盤空間。只需在文件的開頭維護一個偏移量表以鏈接到每個塊。

就壓縮而言,應用運行長度編碼會明顯縮小文件大小,如果它與Minecraft類似,則會依次有很多相同的塊。作爲獎勵,它將在使用拼盤驅動器的計算機上加載速度更快,因爲幾個字節可以等同於數千個塊,而不必爲每個塊讀取一個字節。下面是一個有效的遊程編碼的快速提示:使用一個命令字節,比如說0x00。所有其他字節都與塊關聯,但命令字節將表示信息的非塊位。傳統的行程長度編碼是這樣的:

Source: AAAABBBBBBBCDDDEFA 
Destination: 0x0441074201430344014501460161 
Plaintext: .A.B.C.D.E.F.A 

使用命令字節,省略這將增加大小的序列:

Source: AAAABBBBBBBCDDDEFA 
Destination: 0x00044100074243444444454641. 
Plaintext: ..A..BCDDDEFA 

這具有在數據的「大理石」部分具有明顯的優勢。

另一件事,我建議你使用一個系統來存儲類似於midi格式的數字,儘管是小尾數格式。爲了節省你的谷歌搜索,它的真正意義在於你爲每個用於存儲數字的字節犧牲了一點。如果第8位被設置,則意味着該數字中有另一個字節,並且級聯。例如:

Storing: 65 
Stored as: 0x41 (01000001) //The eighth bit is not set, so this number only occupies 7 bits. 

Storing: 192 
Stored as: 0xC081 (11000000 10000001) //The eighth bit of the first byte is set, so the following byte is part of the number. The second byte doesn't have the eighth bit set, so the number ends there. 

Storing: 612453 
Stored as: 0x72D825 (11100101 1011000 00100101) //The eighth bit of the first two bytes are set, and the third is not, so this number occupies 3 bytes. 

我希望我幫忙提供一些見解。

+0

太棒了,這真的很有用。我以前從來沒有搞錯過編碼,但我理解基礎知識。我將不得不在Google上做一些搜索,以及拼盤驅動器。我可能會將MIDI風格的編碼用於「特殊」塊(比如Minecraft中的TileEntities--比如說我想要一個包含物品的胸部)。謝謝! – Philip 2012-03-01 05:35:37

+0

沒問題。我以前用一個額外的字節存儲數字長度的格式。這很簡單,但對於佔用7個字節或更少的數字,效率並不高,並且我從不使用大於4個字節的數字。當我查閱midi格式時,我很高興用這種巧妙的方式存儲可變長度數字。我很高興我幫助:) – Kaslai 2012-03-01 05:38:48

+0

至於單個文件的東西,我將不得不依靠我的操作系統技能......如果我的塊在磁盤上可變大小,由於外部碎片複製將是可怕的...也許是一個分頁系統的索引在文件的開頭?如果我不得不尋呼分頁索引怎麼辦? * faints * – Philip 2012-03-01 05:40:48

3

數據庫的目的是加速複雜的搜索。你沒有任何搜索正在進行;你有一塊你需要進入內存的數據。對於這項任務,數據庫絕對沒有任何價值。

您需要什麼取決於您正在討論的數據量以及您想要的平臺特定性。你似乎在談論一款2D遊戲,所以該塊不可能是大。常規的C或C++文件IO功能可能會足夠好。最壞的情況下,您可能需要將它們粘貼到異步文件IO和處理的線程中。

真的,只要開始做明顯的事情。如果它成爲一個問題,請嘗試使其與簡單的線程構造異步。你可能不應該走的太遠。

+0

嗯,好吧,不要數據庫。 Ehhhh塊的大小是可變的,但它們越大,其他事情就越快(難以解釋)。他們目前是1024x1024(高達1 MB),但512x512和256x256絕對是選擇。 – Philip 2012-03-01 04:57:20

+0

我會告訴你什麼時候1mb是百日咳...... – fazo 2012-03-01 05:02:18

+0

@Philip:如果你正在談論1MB大塊,你真的不需要做太多特別的事情。只需加載它們並處理它們。再次,如果響應是一個問題,請使用線程。 – 2012-03-01 05:12:38

1

根據我的經驗,這取決於很多因素。我的團隊有一個將數百甚至數千個文件保存到數據庫的系統,並且性能得到了提高。這些文件很小,因此與等待磁盤驅動器啓動或操作系統將文件系統導航到每個單獨文件的延遲相比,讀取和寫入很短。

如果你有幾千個文件小於4 kB頁面,我會用數據庫。如果文件大於該文件,則使用文件。數據庫不會幫助您的吞吐量 - 只有您的延遲。

+0

謝謝,我沒有考慮磁盤延遲。我可能會結束一個數據庫,具體取決於。數據庫可能會傷害我的吞吐量嗎? – Philip 2012-03-01 05:05:41

+0

通過將這些鬆散的文件粘貼到TAR或Zip文件中,您可以獲得相同的優勢。 – 2012-03-01 05:12:04

+0

焦油或拉鍊的缺點是你必須閱讀整個事情。他說他只想一次將部分數據讀入內存。因此,我不會使用單個文件 - 操作系統必須加載整個文件並將其保存在磁盤緩存中。 – danimator 2012-03-01 05:20:22