ここの誰かが全体に光を当てることができることを願って、私は自分の問題に対する答えを探してグーグルのいたるところにいました。
さて、私は 2D オンライン RPG (ロール プレイング ゲーム。ファイナル ファンタジーを考えてみてください。ただし、オンラインです) に取り組んでいます。私はしばらくそれに取り組んできましたが、ちょっとした問題に遭遇しました。現在、圧縮によって問題が解決するかどうか、または単純にループが大きすぎるかどうかについては、100% 確信が持てません。
注: Lidgren Networking ライブラリを使用しています。Lidgren は圧縮をサポートしていないため、他のオプションに関する提案を受け付けています。
私がやろうとしていることに関するいくつかの情報:
マップのすべての情報を含むパケットを送信しようとしています。マップが小さいほど、パケットの速度は速くなりますが、250x250 のマップ (トップダウン、タイル ベース) を送信しようとすると、送信に数分かかります。
これには2つの理論があります。1 つは、その時点でマップのサイズがかなり大きい (約 5MB) ため、しばらく時間がかかるということです。もう 1 つは、マップが非常に大きいため、ループ自体に時間がかかることです。
マップには、文字列、バイト、int32、int16 などが含まれます。バイト配列を必要とする圧縮方法がありますが、すべてのデータをバイト配列に変換する方法について 100% 確信が持てません (私はC# を 1 年ちょっと使っていますが、完全に独学です)。
すべてを考慮すると、ループはかなり大きいです。4 つのタイル レイヤーがあり、すべてをループする必要があります。これが、ループが問題である可能性があると私に信じさせるものです。サーバーを起動すると、すべてのマップがキャッシュされます (つまり、パケットが必要になる前にパケットが作成されます)。そのため、クライアントがマップを必要とするときにマップを送信しても問題はないようです。正直なところ、かなり速いです。
しかし、マップを編集して保存するために送信すると、パケットがサーバーに送信され、サーバーが現在ログインして立っているすべてのクライアントに更新されたマップ パケットを送信するのにかなりの時間がかかる場合があります。その地図。正直なところ、少し時間がかかりすぎました。パケットの圧縮が役立つかもしれないと考えましたが、前述したように、それが問題であると 100% 確信しているわけではありません。
使用中のループは次のとおりです。
public static void cacheMap(Int32 mapNum)
{
int X; int Y;
int MaxX = Types.Map[mapNum].MaxX;
int MaxY = Types.Map[mapNum].MaxY;
// ****** PreAllocate Buffer ******
int mapSize = Marshal.SizeOf(Types.Map[mapNum]);
int tileSize = Marshal.SizeOf(Types.Map[mapNum].Tile[0,0]);
int nLength = mapSize + ((tileSize * MaxX) * MaxY);
NetOutgoingMessage TempBuffer = ServerTCP.sSock.CreateMessage(nLength);
// Must Preallocate //
TempBuffer.Write(mapNum);
// ****** Map Info ******
TempBuffer.Write(Types.Map[mapNum].Name);
TempBuffer.Write(Types.Map[mapNum].Music);
TempBuffer.Write(Types.Map[mapNum].Revision);
TempBuffer.Write(Types.Map[mapNum].Moral);
TempBuffer.Write(Types.Map[mapNum].Weather);
TempBuffer.Write(Types.Map[mapNum].Tileset);
TempBuffer.Write(Types.Map[mapNum].Up);
TempBuffer.Write(Types.Map[mapNum].Down);
TempBuffer.Write(Types.Map[mapNum].Left);
TempBuffer.Write(Types.Map[mapNum].Right);
TempBuffer.Write(Types.Map[mapNum].BootMap);
TempBuffer.Write(Types.Map[mapNum].BootX);
TempBuffer.Write(Types.Map[mapNum].BootY);
TempBuffer.Write(Types.Map[mapNum].MaxX);
TempBuffer.Write(Types.Map[mapNum].MaxY);
// ****** Tiles ******
for (X = 0; X <= MaxX - 1; X++)
{
for (Y = 0; Y <= MaxY - 1; Y++)
{
for (int I = 0; I <= 4; I++)
{
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Layer[I].X);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Layer[I].Y);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Layer[I].Tileset);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Autotile[I]);
}
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Type);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Data1);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Data2);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].Data3);
TempBuffer.Write(Types.Map[mapNum].Tile[X, Y].DirBlock);
Application.DoEvents();
}
}
// ****** Send Map SoundID ******
for (X = 0; X <= MaxX - 1; X++)
{
for (Y = 0; Y <= MaxY - 1; Y++)
{
TempBuffer.Write(Types.Map[mapNum].SoundID[X, Y]);
}
}
TempBuffer.Write(Types.Map[mapNum].Instanced);
Types.MapCache[mapNum].Data = TempBuffer;
}
提供できるヘルプは大歓迎です。さらに情報を提供する必要がある場合は、それを行うことができます。