我正在尝试从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/

10-12 00:38
查看更多