Reputation: 935
I have an event that adds a Block
to a HashSet
when right-clicking with a compass. However, I want to add all blocks of the same type connected to the first block to the set. How should I do this to prevent lag?
Upvotes: 0
Views: 1415
Reputation:
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.
Upvotes: 4