大家在开发minecraft mod的时候可能会遇到一些需要获取连续的方块,所以我这里就给大家提供个思路,有建议或错误可以评论区指出
首先我们需要编写一个方法,用于获取一个方块连起来的方块.
思路:一个方块有东南西北上下六个面,从我们触发的方块开始,依次获取,如果符合条件则递归调用继续获取。这里我没添加筛选的条件,如果需要同类型连起来的方块可以添加一个方块材质的判断,满足则加入列表。
//recode用于记录所有已经获取过的方块,防止两个相邻方块连续递归重复获取对方
//block代表当前正在获取六个面方块的坐标(中心)
//world代表方块当前所在的世界
public static List<BlockPos> getConnectBlock(List<BlockPos> record, BlockPos block,World world)
{
//如果他的上方(Y + 1)方块没有获取过
if (!record.contains(new BlockPos(block.getX(),block.getY() + 1,block.getZ())))
{
//构建他的方块坐标
BlockPos pos=new BlockPos(block.getX(),block.getY() + 1,block.getZ());
//如果上方方块不为空气(其他筛选条件也可以在这添加,例如一定要同类型)
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
//设定一个阈值,防止出现意料之外的事情(获取的方块过多)
if (record.size() < 100)
{
record.add(pos);
//继续递归调用,获取上方方块的六个面
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//下方方块(Y - 1)
if (!record.contains(new BlockPos(block.getX(),block.getY() - 1,block.getZ())))
{
BlockPos pos=new BlockPos(block.getX(),block.getY() - 1,block.getZ());
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
if (record.size() < 100)
{
record.add(pos);
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//东边方块(X + 1)
if (!record.contains(new BlockPos(block.getX() + 1,block.getY(),block.getZ())))
{
BlockPos pos=new BlockPos(block.getX() + 1,block.getY(),block.getZ());
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
if (record.size() < 100)
{
record.add(pos);
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//西边方块(X - 1)
if (!record.contains(new BlockPos(block.getX() - 1,block.getY(),block.getZ())))
{
BlockPos pos=new BlockPos(block.getX() - 1,block.getY(),block.getZ());
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
if (record.size() < 100)
{
record.add(pos);
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//南边方块(Z + 1)
if (!record.contains(new BlockPos(block.getX(),block.getY(),block.getZ() + 1)))
{
BlockPos pos=new BlockPos(block.getX(),block.getY(),block.getZ() + 1);
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
if (record.size() < 100)
{
record.add(pos);
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//北边方块(Z - 1)
if (!record.contains(new BlockPos(block.getX(),block.getY(),block.getZ() - 1)))
{
BlockPos pos=new BlockPos(block.getX(),block.getY(),block.getZ() - 1);
if (world.getBlockState(pos).getBlock() != Blocks.AIR)
{
if (record.size() < 100)
{
record.add(pos);
record = getConnectBlock(record,pos,world);
}
else
{
return record;
}
}
}
//六个面方块都筛选完毕,返回所有通过筛选的方块,即是所有连续的方块
return record;
}
到这里我们的方法已经完成了,触发器可以自己决定,我这里做例子,当方块被破坏时检测与此方块相连的方块数量 包括他自己
//方块破坏事件
@SubscribeEvent
public static void OnBreakBlock(BlockEvent.BreakEvent event)
{
if (!event.getWorld().isRemote)
{
//创建一个包含被破坏方块的列表
List<BlockPos> record=new ArrayList<>();
record.add(event.getPos());
//传入参数,检测相连方块
List<BlockPos> infoList=getConnectBlock(record,event.getPos(),event.getWorld());
event.getPlayer().sendMessage(new TextComponentString("\u4f60\u521a\u521a\u7834\u574f\u4e86 " + infoList.size()));
}
}