迭代所有相同类型的连接块

时间:2016-12-17 21:11:38

标签: java iterator minecraft bukkit

我有一个事件,当用指南针右键单击时,会向Block添加HashSet。但是,我想将连接到第一个块的所有相同类型的块添加到集合中。我该怎么做才能防止滞后?

1 个答案:

答案 0 :(得分:4)

First of all, you make a BlockFace array which represents all the 6 sides of blocks. (Front, back, left, right, above, and underneath).

//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
};

Next, you make a private method that goes through all these blockfaces and checks if the block at that side if of the same type and adds these blocks to a list of blocks that are yet to be checked. We will use this list later.

In this method, results is the Set of all Blocks that are connected to the block that was clicked with the compass, todo is the list of blocks that are yet to be checked the same way.

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);
            }
        }
    }

Finally you use the following method to go through all the blocks that are yet to be checked and call the private method above for all these blocks. This is the most efficient way I could come up with.

    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;
}

Note that you can not run these methods on an aSync thread, because this can lead to a CurrentModificationException and this can cause strange behavior in the game itself, depending on what you use it for.