在我的遊戲好了,所以基本上,這個世界是做出來的瓷磚和地磚被分割成塊(50 * 50瓷磚和瓷磚是16×16),所以整個世界ISN」 t加載到內存中。這些塊被保存到文件,並只需要加載的人(在屏幕上的人與1關閉,屏幕畫面的每一側(上,左,下,右)),以及其他被卸載等。這一切工作精細然而,當加載實際上包含瓷磚塊遊戲邏輯凍結了相當多的(要知道加載文件?),基本上我的問題是我怎麼會讓我目前的方法更快,所以這是幾乎沒有明顯的滯後?如何加載/卸載瓦塊快(C#)
基本上每個塊只包含字節的2D陣列,含有該瓦片型而不是實際的瓷磚類,而字節數組被保存到稍後被加載的文件。 我的塊加載/保存功能:
節能:
public void SaveChunk(int cx, int cy)
{
String chunkname = "";
chunkname = WorldChunks[cx, cy].X + "_" + WorldChunks[cx, cy].Y;
FileStream fileStream = File.Create(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk");
StreamWriter writer = new StreamWriter(fileStream);
String json = JsonConvert.SerializeObject(WorldChunks[cx, cy].myTiles, Formatting.None);
writer.Write(json);
writer.Close();
}
加載:
public void LoadChunk(int xx, int yy)
{
string chunkname = xx + "_" + yy;
if (File.Exists(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk"))
{
//If the chunk is not loaded, Create a new chunk and begin loading it's tiles.
if (WorldChunks[xx, yy] == null)
{
WorldChunks[xx, yy] = new Chunk(xx, yy);
}
System.Diagnostics.Debug.WriteLine("Loading chunk [" + xx + "," + yy + "]");
Stream stream = File.Open(Main.ChunkPath + "\\Chunks\\" + chunkname + ".chnk", FileMode.Open);
StreamReader reader = new StreamReader(stream);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Objects;
WorldChunks[xx, yy].myTiles = JsonConvert.DeserializeObject<byte[,]>(reader.ReadToEnd(), settings);
stream.Close();
System.Diagnostics.Debug.WriteLine("Chunk loaded.. [" + xx + "," + yy + "]");
int x, y;
for (x = 0; x < Main.ChunkSizeX; x++)
{
for (y = 0; y < Main.ChunkSizeY; y++)
{
byte _Type = WorldChunks[xx, yy].myTiles[x, y];
int tx = (xx * ChunkSizeX) + x;
int ty = (yy * ChunkSizeY) + y;
if (_Type > 0)
{
if (Tiles[tx, ty] == null && tx < MaxTilesX && ty < MaxTilesY)
{
Tiles[x + (xx * ChunkSizeX), (yy * ChunkSizeY) + y] = new Tile();
Tiles[(xx * ChunkSizeX) + x, (yy * ChunkSizeY) + y].Type = _Type;
if (ty > GROUND_LEVEL[tx] + 1)
{
//System.Diagnostics.Debug.Write("Below level:" + x + "|" + tx);
Tiles[tx, ty].HasBG = true;
}
}
else continue;
}
}
}
}
}
我試圖改變周圍的CHUNKSIZE,我試過25×16×35x35等等等等..但仍然無濟於事。 那麼我怎樣才能使這些功能更快?任何其他提示/建議將非常感謝!謝謝!
編輯:從我的代碼去秒錶和其他測試的瓶頸是從文件實際加載我甚至取消了瓷磚的擺放,它仍然鎖定了遊戲邏輯,但是我意識到最大的明顯延遲是當我之間的塊和它必須加載更多的塊比平常像這樣: Picturing showing when my game logic takes the biggest hit http://img854.imageshack.us/img854/8031/wcs2.png
現在我可能是塊實際上比那大,但同樣的事情是可能的。
我的保存功能簡單地保存每個瓷磚1個字節,我的文件大小每塊只有2.5kb左右,因爲每個瓷塊有2,500個瓷磚,每個瓷磚1個字節(只保存瓷磚類型)。
所以我沒想到的保存和加載它們將是多大的影響,我有一個異步FILESTREAM以及更早的設置,但表現得幾乎相同。
這裏是我的加載/卸載大塊代碼:
public void CheckChunks()
{
int StartX = (int)Math.Floor(ScreenPosition.X/(ChunkSizeX * 16)) - 2;
int StartY = (int)Math.Floor(ScreenPosition.Y/(ChunkSizeY * 16)) - 2;
if (StartX < 0) StartX = 0;
if (StartY < 0) StartY = 0;
int EndX = (int)Math.Floor((ScreenPosition.X + GraphicsDevice.Viewport.Width)/(ChunkSizeX * 16)) + 2;
int EndY = (int)Math.Floor((ScreenPosition.Y + GraphicsDevice.Viewport.Height)/(ChunkSizeY * 16)) + 2;
if (EndX > MaxChunksX) EndX = MaxChunksX;
if (EndY > MaxChunksY) EndY = MaxChunksY;
for (int x = StartX; x < EndX; x++)
{
for (int y = StartY; y < EndY; y++)
{
if (WorldChunks[x, y] == null)
{
LoadChunk(x, y, true);
if (WorldChunks[x, y] != null)
{
LoadedChunks.Add(WorldChunks[x, y]);
}
break;
}
}
}
foreach (Chunk cc in LoadedChunks)
{
if (cc.X < StartX || cc.Y < StartY || cc.X >EndX || cc.Y > EndY)
{
System.Diagnostics.Debug.WriteLine("Chunk to be unloaded..");
ChunkBuffer.Add(cc);
UnloadChunk(cc);
}
}
foreach (Chunk c in ChunkBuffer)
{
LoadedChunks.Remove(c);
}
ChunkBuffer.Clear();
}
如何遊戲一樣的Minecraft負荷等方面迅速卸下自己的塊?
爲了加快速度,您需要知道代碼中的速度緩慢。配置文件(或至少用'秒錶'測量時間)並從那裏開始。 –
謝謝你,但我忘了提及我已經使用秒錶,甚至刪除了部件,以查看瓶頸在哪裏。它是從文件實際加載的,但我不確定它是否與反序列化或從文件中讀取(很可能是閱讀)。我會做進一步的測試,看看它究竟在哪裏。 – Brassx
我也在製作類似的遊戲。我可以問一下你的「世界塊」是什麼,我正在猜測一堂課?另外,你如何跟蹤哪些塊被加載/卸載?我爲此使用了一個List,但我正在尋找其他人從事類似工作的看法,以瞭解他們是如何做到的。謝謝! – user9993