私はXNAでトップダウンのシューティングゲームを作成しており、マップに長方形の衝突が必要です。
マップの衝突壁は、次の形式のテキストファイルに保存されます。rect[0,0,1024,8]
値は、長方形(x、y、幅、高さ)の定義に対応しています。
私は、地図画像のデータを読み書きできない別のアプリケーションを作成し、黒(または壁の任意の色)のピクセルを見つけて、そこに長方形を作成できると考えていました。基本的に、このプログラムは衝突に必要な長方形を生成します。理想的には、それはピクセルパーフェクトであり、すべての壁をカバーする幅1ピクセルごとに1000個の長方形のようなものが必要になります。
これらの長方形(または私が言うべき正方形)のどれが互いに隣接しているかを検出し、それらをより大きな(しかし同じ領域をカバーしている)長方形に接続する方法はありますか?
例えば。10 x 2の壁があるとします。プログラムは、それぞれ1ピクセルの高さの20個の異なる長方形を生成します。これらの長方形が隣接していることを効率的に検出し、20個の異なる小さなピクセルの長方形ではなく、壁全体を覆う10 x 2の長方形を自動的に作成するにはどうすればよいですか?
編集:私は自分の目的に合った解決策を考え出しました。将来の参考のために、私のコードは以下のとおりです。
//map is a bitmap, horizontalCollisions and collisions are List<Rectangle>s
for (int y = 0; y < map.Height; y++) //loop through pixels
{
for (int x = 0; x < map.Width; x++)
{
if (map.GetPixel(x, y).Name == "ff000000") //wall color
{
int i = 1;
while (map.GetPixel(x + i, y).Name == "ff000000")
{
if (i != map.Width - x)
{
i++;
}
if (i == map.Width - x)
{
break;
}
}
Rectangle r = new Rectangle(x, y, i, 1);//create and add
x += i - 1;
horizontalCollisions.Add(r);
}
}
}
for (int j = 0; j < horizontalCollisions.Count; j++)
{
int i = 1;
Rectangle current = horizontalCollisions[j];
Rectangle r = new Rectangle(current.X, current.Y + 1, current.Width, 1);
while(horizontalCollisions.Contains(r))
{
i++;
horizontalCollisions.Remove(r);
r = new Rectangle(current.X, current.Y + i, current.Width, 1);
}
Rectangle add = new Rectangle(current.X, current.Y, current.Width, i);
collisions.Add(add);
}
//collisions now has all the rectangles
基本的に、ピクセルデータを水平方向にループします。壁のピクセルに遭遇すると、カウンターを停止し、(whileループを使用して)壁以外のピクセルに当たるまで、カウンターを1つずつ右に移動します。次に、その幅の長方形を作成し、続行します。このプロセスの後、それぞれ1pxの高さの長方形の大きなリストが作成されます。基本的に、水平線の束。次のループは水平線を通過し、上記と同じプロセスを使用して、同じX値と同じ幅値(y + 1)を持つ長方形があることを検出します。これは、1つの大きな長方形が作成され、使用された長方形がリストから削除されるまで、増加し続けます。