2016-12-17 1 views
0

コンパスを右クリックしたときにをHashSetに追加するイベントがあります。しかし、最初のブロックに接続された同じタイプのブロックをすべてセットに追加したいと思います。ラグを防ぐためにこれをどうすればいいですか?同じタイプのすべての接続されたブロックを反復する

+0

実際にブロック全体を追加する必要はありますか?たとえば、遅れを防ぐために、座標とIDを追加するだけです。 – Squiddie

+0

ブロッククラスには、私が必要とする座標が含まれています。場所はフロートの指針と方向を持っています。 – TsundereBug

+0

「すべてのブロック...最初のブロックに接続しました」と書くと、ブロックや他のものに隣接する6つのブロック(基本方向、上下)を意味しますか?何らかの明確化がおそらく役に立ちます。「つながっている」とはあらゆることを意味します。 –

答えて

4

まず、ブロックの6辺すべてを表すBlockFaceの配列を作成します。 (前、後、左、右、上、下)。

//These are all the sides of the block 
private static final BlockFace[] faces = { 
    BlockFace.DOWN, 
    BlockFace.UP, 
    BlockFace.NORTH, 
    BlockFace.EAST, 
    BlockFace.SOUTH, 
    BlockFace.WEST 
}; 

次に、あなたは、これらすべてのblockfacesとチェックを通過プライベートメソッドを作る場合、その側のブロックに同じタイプの場合は、チェックすることがまだあるブロックのリストにこれらのブロックを追加します。このリストは後で使用します。

このメソッドでは、resultsは、コンパスでクリックされたブロックに接続されているすべてのブロックのセットです。todoは、同じ方法でまだチェックされていないブロックのリストです。

private void getConnectedblocks(Block block, Set<Block> results, List<Block> todo) { 
    //Here I collect all blocks that are directly connected to variable 'block'. 
    //(Shouldn't be more than 6, because a block has 6 sides) 
    Set<Block> result = results; 

    //Loop through all block faces (All 6 sides around the block) 
    for(BlockFace face : faces) { 
     Block b = block.getRelative(face); 
     //Check if they're both of the same type 
     if(b.getType() == block.getType()) { 
      //Add the block if it wasn't added already 
      if(result.add(b)) { 

       //Add this block to the list of blocks that are yet to be done. 
       todo.add(b); 
      } 
     } 
    } 

最後に、次の方法を使用して、まだチェックされていないすべてのブロックを調べ、これらすべてのブロックについて上記のプライベートメソッドを呼び出します。これが私が思いつく最も効率的な方法です。

public Set<Block> getConnectedblocks(Block block) { 
    Set<Block> set = new HashSet<>(); 
    LinkedList<Block> list = new LinkedList<>(); 

    //Add the current block to the list of blocks that are yet to be done 
    list.add(block); 

    //Execute this method for each block in the 'todo' list 
    while((block = list.poll()) != null) { 
     getConnectedblocks(block, set, list); 
    } 
    return set; 
} 

これはCurrentModificationExceptionにつながることができ、これはあなたがそれを使用するものに応じて、ゲーム自体に奇妙な動作を引き起こす可能性がありますので、あなたが、非同期スレッドでこれらのメソッドを実行することはできません注意してください。

+0

これは、同じ "グループ"内のすべてのブロックを取得しますか?私が8x8x8の立体ゴールドキューブを持っているならば、 'todo'は8^3ブロックをすべて含んでいますか? – TsundereBug

+0

@moo_we_all_do申し訳ありません最後の方法を含めるのを忘れてしまいました。いいえ、 'todo'にはすべてのブロックが含まれているわけではなく、まだチェックされていないブロックだけです。 publicメソッド 'getConnectedblocks(Block block)'の結果は、すべてのブロック(あなたの例ではすべての8^3)ブロックを含んでいます。 –

関連する問題