2016-03-28 13 views
1

私はもともと、タイルの2次元配列を使用して、さまざまな内容の手続き生成マップを格納していました。手続きマップの生成 - 隣接するタイルを決定

各タイルには隣接するリストが含まれているため、どのタイルが最も近いかを各タイルが知ることができ、8つの異なる辺(直線に隣接し、斜めに隣接している)に触れます。

一般的なアイデアは、Amitのポリゴンマップ生成から取得しましたが、私はボロノイの代わりにグリッド設定を使用して単純化しようとしましたが、私は当初考えるよりも多くのトラブルに遭遇しました。私の現在の苦境は、2次元アレイを廃止したときに隣接関係を理解することです。

これは私がリストに変更する前に、それをしていた方法である。

private void ConstructAdjacencyList() { 

    // Create Adjacency List 
    for (int x = 0; x < mapWidth; x++) { 
     for (int y = 0; y < mapHeight; y++) { 
      // Bool to find position of point 
      bool omitLeft = false;  bool omitRight = false; 
      bool omitTop = false;  bool omitBottom = false; 
      // Enable bools based on position, reset on each loop    
      if (x == 0) 
       omitLeft = true;     
      else if (x == mapWidth - 1) 
       omitRight = true;    
      if (y == 0) 
       omitTop = true;    
      else if (y == mapHeight - 1) 
       omitBottom = true; 

      // Add entries to list based on bool settings 
      if (!omitLeft) { 
       // Left center 
       islandMap[x,y].adjacent.Add(islandMap[x-1,y]); 
       if (!omitTop) 
        islandMap[x,y].adjacent.Add(islandMap[x-1,y-1]); 
       if (!omitBottom) 
        islandMap[x,y].adjacent.Add(islandMap[x-1,y+1]); 
      } 

      if (!omitTop) // Top Center 
       islandMap[x,y].adjacent.Add(islandMap[x,y-1]); 
      if (!omitBottom) // Bottom Center 
       islandMap[x,y].adjacent.Add(islandMap[x,y+1]); 

      if (!omitRight) { 
       // Right Center 
       islandMap[x,y].adjacent.Add(islandMap[x+1,y]); 
       if (!omitTop) 
        islandMap[x,y].adjacent.Add(islandMap[x+1,y-1]); 
       if (!omitBottom) 
        islandMap[x,y].adjacent.Add(islandMap[x+1,y+1]); 
      }    
     } 
    } // End Adjacency 

    Debug.Log ("Adjacencies Built"); 
} 

のx、yの値は、現在(islandMap.pointに次のように生成されたxとyの値を格納するベクトル2Dを保持しています。 )

public MapController() { 
    width = height = (int)Mathf.Sqrt (tileCount); 

    // Lists for points 
    var points = new List<Vector2>(); 

    // Build a random set of points. 
    for (float x = 0; x < width; x++) { 
     for (float y = 0; y < height; y++) { 
      points.Add(new Vector2(x,y)); 
     } 
    } 

    map = new Map (points, width, height, lakeTreshold); 
} 

、マップ自体は現在、次があります。他の方法Sとともに

public class Map { 
    Func<Vector2, bool> inside; // Contains function to randomly seed area 
    bool needsMoreRandomness; 

    public List<Tile> islandMap; // Previously was Tile[,] islandMap 
    public int mapWidth { get; private set; } // Calculated as Sqrt(totalPoints) 
    public int mapHeight { get; private set; } 

私は現在固執しているConstructAdjacencyList()メソッドとしてuch。

それでは、配列の位置付けに頼らずに、周辺ポイントの隣接リストを構築するにはどうすればよいですか?私は一時的にアレイからリスト全体を参照できますか?この2次元配列のリスト全体の各タイルへの参照を配置し、隣接関係を設定して情報を失うことなく配列を削除しますか?私はそれが唯一の参照を使用すると考えているので、それは問題ないはず...各タイルは、それがそうのように構築されたときの順序を保存するためのインデックスが含まれています

これが長すぎる場合
foreach (var point in points) { 
     var p = new Tile { index = islandMap.Count, point = point }; 
     p.border = point.x == 0 || point.x == mapWidth || point.y == 0 || point.y == mapHeight; 
     islandMap.Add (p); 
     tileLookup[point] = p; 
    } 

申し訳ありません... Iちょうどそれがかなり大規模であることが分かりました.-

+0

がこれに対処するいくつかの方法がありますが、あなたのタイルマップのサイズが指示することができますどのソリューションがより適切です - あなたはどのくらい多くのタイルを扱っていますか? – Pikalek

+0

こんにちはPikalek、返信いただきありがとうございます。私は、現在最大300ポイントを入力することを検討していますが、現在は300ポイントを下回っています。計算時間では、それがうまくいくならば、正直なところ、それほど大きな取引ではありません。 – Ben

+0

また、私は次のようにしようとしていました: 'Tile [、] tempArray = new Tile [mapWidth、mapHeight]; \t \t int count = 0;用{ \t \t \t(X ++; X Ben

答えて

0

ポイントの順番を乱すことを何もしていないと仮定すると、1D list/array as 2D list/arrayを扱うことができます。私がリンクしている例はCですが、アイデアの言語には無関係です。

初期化中に一度だけこれを行うと仮定すると、比較的低い点数を指定すると、ポイントリストをループする関数で簡単に強制することができます& picks必要に応じて隣人を救う。私のC#が少し錆びですが、私はこのような何かについて話している:

private List<Vector2> getAdjacenctPointList(List<Vector2> pointsList, Vector2 point){ 
    var adjacencyList = new List<Vector2>(); 
    foreach (var pt in pointList){ 
    var offset = Math.abs(pt.x - point.x) + Math.abs(pt.y - point.y); 
    if(offset > 0 && offset <= 1.0){ 
     adjacencyList.add(pt); 
    } 
    } 
    return adjacencyList; 
} 
+1

if節を終了するための '}'がありません。 – juunas

+0

回答をいただきありがとうございました。実際には、リストを2次元配列として扱うのと同じ基本的な考え方を使って、これを簡単な方法で解決しました。しかし私は文字通りそのようにしました。私は答えとして私自身も投稿します。 – Ben

0

私はこれと一緒に行った、最終的な答えが必要な作業量が最小だったと私は上記の投稿私の元の2D配列のコードを再利用することができ一時的な2次元配列を作成し、そこにすべての参照を格納することでした。必要に応じてすべての隣接関係を作成し、2次元配列の(スコープを失うだけで)破棄します。

2次元配列システムを使用した実際の方法を示します。ループの入れ子になっ続く最初のカップルの文はそれが取ったすべてだった:

private void ConstructAdjacencyList() { 
    Tile[,] tempArray = new Tile[mapWidth, mapHeight]; 

    int count = 0; 

    // Populate the temp 2D array with list references 
    for (int x = 0; x < mapWidth; x++) { 
     for (int y = 0; y < mapHeight; y++) { 
      tempArray[x,y] = islandMap[count]; 
      count++;    
     } 
    } 

    // Create Adjacency List using our TempArray 
    for (int x = 0; x < mapWidth; x++) { 
     for (int y = 0; y < mapHeight; y++) { 
      // Bool to find position of point 
      bool omitLeft = false;  bool omitRight = false; 
      bool omitTop = false;  bool omitBottom = false; 
      // Enable bools based on position, reset on each loop    
      if (x == 0) 
       omitLeft = true;     
      else if (x == mapWidth - 1) // Optimize with if else to split checks in half. 
       omitRight = true;    
      if (y == 0) 
       omitTop = true;    
      else if (y == mapHeight - 1) 
       omitBottom = true; 

      // Add entries to list based on bool settings 
      if (!omitLeft) { 
       // Left center 
       tempArray[x,y].adjacent.Add(tempArray[x-1,y]); 
       if (!omitTop) 
        tempArray[x,y].adjacent.Add(tempArray[x-1,y-1]); 
       if (!omitBottom) 
        tempArray[x,y].adjacent.Add(tempArray[x-1,y+1]); 
      } 

      if (!omitTop) // Top Center 
       tempArray[x,y].adjacent.Add(tempArray[x,y-1]); 
      if (!omitBottom) // Bottom Center 
       tempArray[x,y].adjacent.Add(tempArray[x,y+1]); 

      if (!omitRight) { 
       // Right Center 
       tempArray[x,y].adjacent.Add(tempArray[x+1,y]); 
       if (!omitTop) 
        tempArray[x,y].adjacent.Add(tempArray[x+1,y-1]); 
       if (!omitBottom) 
        tempArray[x,y].adjacent.Add(tempArray[x+1,y+1]); 
      }    
     } 
    } // End Adjacency 

    Debug.Log ("Adjacencies Built"); 
} 

私はそれが望んでいたとして、これが働いたことを確認するために、私は視覚的に1つのランダムキューブを設定することで、それをテストし、すべての地域への周りの様々なポイントをテスト間違いがないことを確認してください。

予想通り最終的な結果は、以下に示す、次のとおりです。助けを

Element Selection

感謝:)

関連する問題