私はクライアントサーバータイルベースのゲームに取り組んでいます。クライアントはデータを3次元で保持しstd::vector
、各フレームでそのコンテンツをサーバーが送信するコンテンツと比較します(サーバーから送信さstd::vector
れたデータで満たされた別のコンテンツがクライアント側にあります)。
これで、クライアント側のマップは15x11タイルで構成され、各タイルには10個のオブジェクトが配置されたデータが保持されるため、で15 * 11 * 10=1650要素を取得し std::vector
ます。
両方のデータを比較していてstd::vector
、何かが変更された場合は、違いに応じて、新しいオブジェクトを作成/オブジェクトを削除/オブジェクトを移動します。これが私のやり方です:
std::vector<IdAndPosition> clientIds;
std::vector<IdAndPosition> serverIds;
// Fill client ids
for(unsigned int i = 0; i < m_tiles.size(); i++)
{
for(unsigned int j = 0; j < m_tiles[i].size(); j++)
{
for(unsigned int s = 0; s < m_tiles[i][j].getObjects().size(); s++)
{
clientIds.push_back(IdAndPosition(m_tiles[i][j].getObjectAtPosition(s)->getId(), i, j, s));
}
}
}
// Fill server ids
for(unsigned int i = 0; i < g_gameStateData.m_gameObjects.size(); i++)
{
for(unsigned int j = 0; j < g_gameStateData.m_gameObjects[i].size(); j++)
{
for(unsigned int s = 0; s < g_gameStateData.m_gameObjects[i][j].size(); s++)
{
serverIds.push_back(IdAndPosition(g_gameStateData.m_gameObjects[i][j][s].second, i, j, s));
}
}
}
for (int i = 0; i < serverIds.size(); i++)
{
IdAndPosition& serverId = serverIds[i];
bool found = false;
for(int j = 0; j < clientIds.size(); j++)
{
IdAndPosition& clientId = clientIds[j];
found = serverId.id == clientId.id;
if(found)
break;
}
if(!found)
{
// If not found, create that object
// tileX // tileY
m_tiles[serverId.pos[0]][serverId.pos[1]].addObjectAtPosition(
TGameObjectFactory::createGameObject(g_gameStateData.m_gameObjects[serverId.pos[0]][serverId.pos[1]][serverId.pos[2]].first), // Game object
serverId.pos[2] // Position at stack
);
// And set it's individual id
m_tiles[serverId.pos[0]][serverId.pos[1]].getObjectAtPosition(serverId.pos[2])->setId(g_gameStateData.m_gameObjects[serverId.pos[0]][serverId.pos[1]][serverId.pos[2]].second);
}
}
for (int i = 0; i < clientIds.size(); i++)
{
IdAndPosition& clientId = clientIds[i];
bool found = false;
for(int j = 0; j < serverIds.size(); j++)
{
IdAndPosition& serverId = serverIds[j];
found = serverId.id == clientId.id;
if(found)
break;
}
if(!found)
{
// If not found, create empty object at this position
// tileX // tileY
m_tiles[clientId.pos[0]][clientId.pos[1]].addObjectAtPosition(
TGameObjectFactory::createGameObject(NO_GAME_OBJECT_ID), // Empty game object (we're removing deprecated one)
clientId.pos[2] // Position at stack
);
}
}
問題は、デバッグモードでその関数(〜90から〜20 fps)を呼び出すために、パフォーマンスが大幅に低下することです。各フレームを通過するのにかなりの量のデータがあることは知っていますが、それほど遅くならないようにどのように設計できるかわかりません。
Visual Studio 2012のパフォーマンス分析を使用して、最大のパフォーマンス低下の正確な原因を突き止めました。その結果は次のとおりです。
だから、それが主な理由のよう[] operator
に見えます。std::vector