壁が四角いブロックでできているゲームを作っています。壁は、次のように 2 次元グリッド上に配置されます。
[X][X][X][X]
[ ][X][ ][ ]
[ ][X][ ][ ]
[ ][X][ ][ ]
現在、衝突検出を最適化しているため、壁の数を最小限に抑えることができます。上記の場合、壁ブロックは7つですが、ブロックを組み合わせると2つの壁しかありません。これらの結合された壁を見つけるための最適な解決策を見つけるのに苦労しており、検索が開始されるブロックに応じてさまざまな結果が得られます (ブロックは順序付けされていないリストに格納され、順序は配置された順序から取得されます)編集者)。これを解決する方法について何か考えはありますか?かなり初歩的なことのはずですが、ほら、今日は金曜日で、正しく機能できません。:)
これが現時点での私の次善のコードです。基本的に、水平方向と垂直方向の「連続性」の両方について2つのチェックを行い、どちらが優れているかをチェックします。また、「既に処理された」壁のブロックを保存するため、2 度認識されることはありませんが、もちろんこれにより交差点でファンキーになります。
public void CreateCollidersForExport()
{
List<Wall> handledWalls = new List<Wall>();
foreach (Wall w in walls)
{
if (handledWalls.Contains(w)) continue;
handledWalls.Add(w);
// Search how many walls there is horizontally
Vector3 horizontalCenter = new Vector3(w.X, w.Y, w.Z);
List<Wall> tmpWallsHorizontal = new List<Wall>();
tmpWallsHorizontal.Add(w);
foreach (Wall other in walls)
{
if (handledWalls.Contains(other) || tmpWallsHorizontal.Contains(other)) continue;
bool canAdd = false;
foreach (Wall _w in tmpWallsHorizontal)
{
if (other.X == _w.X + Wall.size && other.Y == _w.Y && other.Z == _w.Z)
{
canAdd = true;
horizontalCenter.X += Wall.size / 2;
break;
}
else if (other.X == _w.X - Wall.size && other.Y == _w.Y && other.Z == _w.Z)
{
canAdd = true;
horizontalCenter.X -= Wall.size / 2;
break;
}
}
if (canAdd)
{
tmpWallsHorizontal.Add(other);
}
}
// Search how many walls there is vertically
Vector3 verticalCenter = new Vector3(w.X, w.Y, w.Z);
List<Wall> tmpWallsVertical = new List<Wall>();
tmpWallsVertical.Add(w);
foreach (Wall other in walls)
{
if (handledWalls.Contains(other) || tmpWallsVertical.Contains(other)) continue;
bool canAdd = false;
foreach (Wall _w in tmpWallsVertical)
{
if (other.X == _w.X && other.Y == _w.Y && other.Z == _w.Z + Wall.size)
{
canAdd = true;
verticalCenter.Z += Wall.size / 2;
break;
}
else if (other.X == _w.X && other.Y == _w.Y && other.Z == _w.Z - Wall.size)
{
canAdd = true;
verticalCenter.Z -= Wall.size / 2;
break;
}
}
if (canAdd)
{
tmpWallsVertical.Add(other);
}
}
if (tmpWallsHorizontal.Count > tmpWallsVertical.Count)
{
// tmpWallsHorizontal has the longest "wall" now
}
else if (tmpWallsVertical.Count > tmpWallsHorizontal.Count)
{
// tmpWallsVertical has the longest "wall" now
}
else
{
// Both ways are the same length
}
}
}