从中心位置迭代世界中的 3 维半径

Iterate through 3 dimensional radius in world from center position

我正在尝试获取 3 维世界(在本例中为 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 参数和 returns 一个 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 进行排序。供参考:

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

当然,这个方法实际上并不是从播放器开始向外工作的。它只是您原始方法的更清晰和扩展的版本,应该可以满足您的需求。如果您正在处理非常大的半径,那么使用它可能不是一个好主意,因为您必须处理整个立方体。