-1

这是我在我的世界中寻找自由空间的方法。世界由可碰撞和不可碰撞的块组成。我不希望暴徒在可碰撞的块中生成,因为它们无法移动。但是,此方法无法正常工作,我该如何改进它以使代码实际上在空闲空间中生成所有小怪?

所有的块都是随机生成的。

public int findSpawnX(int limit) {
    int xx = random.nextInt(limit) / 16; //find a random x coordinate and divide it by 16 to snap it to a block.

    if (getBlock(xx, 0).solid()) findSpawnX(limit); //check if xx is at a solid block, if so then redo the method.
    return xx; // if it is not solid then return the coordinate.
}

此代码有效。但是有些生物会成块生成。我希望所有随机生成的生物都不会生成在实心块中。

4

5 回答 5

1

您的问题是您永远不会更改xx再次调用该方法的值,因此它始终保持为第一个值。更改if (getBlock(xx, 0).solid()) findSpawnX(limit);if (getBlock(xx, 0).solid()) xx = findSpawnX(limit);将起作用。

于 2013-08-05T15:48:42.920 回答
1

在失败时递归调用你的函数不是好的编码(除了你的代码的问题)。而是采用迭代方法:

public int findSpawnX(int limit) {
    int xx;
    do
    {
       xx = random.nextInt(limit) / 16;
    }
    while (getBlock(xx, 0).solid());
    return xx;
}
于 2013-08-05T15:49:59.623 回答
0

虽然我不明白“并将其除以 16 以将其捕捉到一个块中。” 代码中主要的低效率是不必要的递归调用(您的方法调用自身的地方)。这可以持续很长时间,一个方法调用自己,调用自己,然后调用自己......

改用循环:

 while(getBlock(xx, 0).solid()) {
     xx = random.nextInt(limit) / 16;
 }
于 2013-08-05T15:54:37.617 回答
0

我要做的是获取您的随机坐标,然后将其用作您位置的种子。假设位置有效(未阻塞)返回它。否则以螺旋方式扩展,以循环方式反复检查块。在二维空间中,您可以按以下顺序检查块:

XXXXXXXXXX
XXXX543XXX
XXXX612XXX
XXXX789XXX
XXXXXXXXXX

螺旋向上直到你找到一个空块,在你的游戏世界中具有相似的相对位置。同样,这是假设您的通用方法有效,唯一的问题是,如果它找到一个阻塞的坐标,它没有处理这种情况。我强烈建议您彻底测试的假设!

于 2013-08-05T15:50:21.653 回答
0

我想你的solid方法或getBlock方法都有问题,如果沿着x迭代(假设至少有1个空闲块/瓦片)不起作用,那么它必须是你如何检索块的错误,或者这是固体的问题。

//may go into an infinite loop if all blocks along x are solid
//could be solved quite inefficiently by buffering the block positions
//in an array and also using this to prevent checking the same block twice
//or instead, you could iterate along x and check if there's a non-solid
//block and return its position.
//Assuming your levels are procedurally generated, this should be fine.
public int findSpawnX(int limit) {
    int xx = random.nextInt(limit) / blockWidth;
    while(getBlock(xx, 0).solid()) {
        xx = random.nextInt(limit) / blockWidth;
    }
    return xx;
}

我对此事的看法是,您(假设其他一切正常)应该实现一个 findSpawn / trySpawn 过程,该过程使用初始位置 (x, y) 作为种子,以某种模式进行迭代,以更有效地找到关卡中的生成位置. 沿着两个轴而不是一个轴。

另一个注意事项:我经常看到的是 getBlock / getTile 程序进行划分,以减少源代码其他部分的代码量并提高可读性..您可能需要记住这一点。

希望在一定程度上有所帮助!

于 2013-08-05T20:53:46.633 回答