ボードゲームの RISK に少し似たゲーム、または Total War シリーズのキャンペーン セクションに取り組んでいます。現在、リージョン システムの実装は機能していますが、パフォーマンスが悪いため、特定のコマンドの後でゲームがハングします。私はそれをより良くすることが可能であると確信しています。
私がしたいこと
世界地図などの地図を表示し、それを地域 (国など) に分割できるようにしたいと考えています。地域をクリックして選択し、ユニットをそれらに送信し、隣接する地域を取得できるようにしたいと考えています。
私が試したこと
マップは 3 つのファイルで定義されます。
- 次のようにフォーマットされたデータを含むテキスト ファイル。
"Region Name" "Region Color" "Game-related information" ["Adjacent Region 1", "Adjacent Region 2", ...]'
- 各領域が黒い境界線で区切られ、独自の色を持つ画像ファイル。したがって、たとえば、2 つの領域が存在する可能性があります。一方は RGB 値 255, 0, 0 (赤) を持ち、もう一方は 255, 255, 255 (白) を持ちます。それらは黒い枠で区切られています (ただし、これはアルゴリズムが機能するために必要ではありません)。
- 画面に描画される実際の画像である別の画像ファイル。それは「見栄えの良い」マップです。
このようなカラー マップの例:
(すべての白い部分は、現在の実装では同じ領域に評価されます。すべてが異なる色を持っていると想像してください)。
これらのファイルをロードするときは、まずカラー イメージをロードします。次に、テキスト ファイルを読み込み、各行を調べます。必要に応じて、正しい設定でリージョンを作成します。単にデータを読み取るだけなので、ここでは実際のパフォーマンス ヒットはありません。次に、一連の Region オブジェクトが作成され、正しい色が与えられます。
この段階では、すべてが正常に機能します。領域をクリックして、カラー イメージのピクセル データを確認し、リスト内のすべての領域を調べて、その特定のピクセルの色に一致する領域を見つけることができます。
問題
ただし、ここでパフォーマンス ヒットが発生します。
問題 1: 単位
各プレイヤーはたくさんのユニットを持っています。これらのユニットをリージョンでスポーンできるようにしたいと考えています。赤い領域でユニットをスポーンしたいとしましょう。ファイル内のすべてのピクセルを調べ、赤いピクセルにヒットしたら、そこにユニットを配置します。
for(int i = 0; i < worldmap.size(); i++) {
for(int j = 0; j < worldmap[i].size(); j++) {
if(worldmap[i][j].color == unit_color) {
// place it here
}
}
}
この疑似コードを一目見ただけで、これがうまく機能しないことがわかります。とにかく、まともなペースではありません。
問題 2: 領域の色付け
もう 1 つの問題は、「見栄えの良い」マップでプレイヤーが所有する地域に色を付けたいということです。プレイヤー 1 が青、赤、緑の 3 つの地域を所有しているとします。次に、ワールドマップを調べて、カラー画像で青、赤、緑のピクセルを見つけ、「見栄えの良い」マップでそれらのピクセルをプレイヤーの色の透明バージョンで色付けします。
ただし、これも非常に重い操作であり、数秒かかります。
聞きたいこと
これはターンベースのゲームであるため、時々ゲームが少し遅くなることはそれほど大きな問題ではありません。しかし、この醜いコードを書いているのは私の好みではありません。リージョンの各ポイントをフロートとして保存するなど、他のオプションを検討しましたが、それはメモリに大きな負荷がかかります (64 ビット x 3000x1000 解像度の画像はかなりの量です)。
このために作成されたアルゴリズムがあるかどうか、またはプロセッサを解放するためにより多くのメモリを使用する必要があるかどうか疑問に思っていました. 他のゲームとその方法を探しましたが、役に立ちませんでした。これに関するソースコードや記事をまだ見つけていません。
この質問には意図的にあまり多くのコードを入れていません。これはすでにかなり長く、コードはアプリケーションの他の部分に多くの依存関係があるためです。ただし、問題を解決するために必要な場合は、できるだけ早く投稿します。
前もって感謝します!