我正在尝试从3D世界中获取半径内的所有位置(在本例中为Minecraft游戏),这是我使用的当前代码。
public static List<BlockPos> getBlocksInRadius(double radius) {
List<BlockPos> circleblocks = new ArrayList<>();
int centralx = mc.player.posX;
int centraly = mc.player.posY;
int centralz = mc.player.posZ;
for (int x = centralx - radius; x <= centralx + radius; x++) {
for (int z = centralz - radius; z <= centralz + radius; z++) {
for (int y = centraly - radius; y < centraly + radius; y++) {
double dist = mc.player.getDistance(x, y, z);
if (dist < radius) {
BlockPos l = new BlockPos(x, y, z);
circleblocks.add(l);
}
}
}
}
return circleblocks;
}
该方法从最远的x坐标开始,并不断靠近玩家。我希望它从中心x,y,z开始迭代,然后增加与播放器的距离。这是为了更容易找到最靠近玩家的方块x。任何帮助将不胜感激!
最佳答案
根据半径的大小,可以尝试使用静态方法BlockPos::getAllInBox
。似乎没有任何官方文档,但看起来它需要两个BlockPos
参数并返回一个Iterable<BlockPos>
。它在两个参数之间的多维数据集中找到所有块,因此您可能希望将其放在播放器上居中。
这就是我要做的。该代码尚未经过测试,您可能需要对其进行调整以适应所有1.14和1.13更改,但是理论上应该相同,只是名称更改。
BlockPos playerPos = player.getPosition(); // Or some other method of getting a BlockPos of the player
positiveRadiusPosition = playerPos.add(radius, radius, radius); // Gets one corner of the cube in the positive X, Y, and Z direction
negativeRadiusPosition = playerPos.add(-1 * radius, -1 * radius, -1 * radius); // Gets the opposite corner
Iterable<BlockPos> cubeResult = BlockPos.getAllInBox(positiveRadiusPosition, negativeRadiusPosition);
for (BlockPos pos: cubeResult) {
// cubeResult will contain blocks that are outside of the sphere with the
// radius you want. If that's okay, cool! If that's not okay, you should
// check each pos' distance from the player. If it's outside of the radius,
// remove it from the list.
}
现在,您需要找出最接近的块。我将使用的方法是使用Comparator对Iterable进行排序,然后将其复制到List中。以供参考:
public static Iterator sortedIterator(Iterator it, Comparator comparator) {
List list = new ArrayList();
while (it.hasNext()) {
list.add(it.next());
}
Collections.sort(list, comparator);
return list.iterator();
}
在比较器中,您应该检查播放器到每个块的距离。
public static double getDistanceToEntity(Entity entity, BlockPos pos) {
double deltaX = entity.posX - pos.getX();
double deltaY = entity.posY - pos.getY();
double deltaZ = entity.posZ - pos.getZ();
return Math.sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
}
当然,此方法实际上并不从播放器开始而是向外进行。它只是原始方法的更干净和扩展的版本,可以执行您想要的操作。如果您使用的半径很大,那么使用它可能不是一个好主意,因为您必须使用整个立方体。
关于java - 从中心位置遍历世界的3维半径,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58924319/