这是我在我的世界中寻找自由空间的方法。世界由可碰撞和不可碰撞的块组成。我不希望怪物在可碰撞的块中产生,因为它们无法移动。但是,这种方法不能正常工作,我如何改进它以使代码实际上在自由空间中产生所有怪物?
所有块都是随机生成的。
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.
}
此代码有效。但是一些小怪在街区产卵。我希望所有随机产生的怪物都不会在固体块中产生。
答案 0 :(得分:1)
您的问题是,在再次调用该方法时,您永远不会更改xx
的值,因此它始终作为第一个值保留。将if (getBlock(xx, 0).solid()) findSpawnX(limit);
更改为
if (getBlock(xx, 0).solid()) xx = findSpawnX(limit);
会奏效。
答案 1 :(得分:1)
在失败时递归调用函数不是很好的编码(除了the problem with your code)。而是采用迭代方法:
public int findSpawnX(int limit) {
int xx;
do
{
xx = random.nextInt(limit) / 16;
}
while (getBlock(xx, 0).solid());
return xx;
}
答案 2 :(得分:0)
我要做的是获取随机坐标,然后将其用作您职位的种子。假设该位置有效(未被阻止)返回它。否则以螺旋形扩展,以迭代方式检查圆形螺旋图案中的块。在二维空间中,您可以按以下顺序检查块:
XXXXXXXXXX
XXXX543XXX
XXXX612XXX
XXXX789XXX
XXXXXXXXXX
直到找到一个空块,然后在游戏世界中具有相似的相对位置。同样,这假设你的一般方法是有效的,唯一的问题是,如果它找到了一个被阻塞的坐标,它就没有处理这种情况。一个假设我强烈建议你彻底测试!
答案 3 :(得分:0)
虽然我不理解“并将其除以16以将其捕捉到块。”代码中的主要低效率是不必要的递归调用(您的方法调用自身)。这可以持续很长时间,一个调用自身的方法,调用自身,然后调用自己......
改为使用循环:
while(getBlock(xx, 0).solid()) {
xx = random.nextInt(limit) / 16;
}
答案 4 :(得分:0)
我认为你的solid方法或getBlock方法存在问题,如果沿x迭代(假设至少有1个空闲块/ tile)不起作用那么它必须是你如何检索它的错误块,或者它是固体的问题。
//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程序执行分区,以减少源代码的其他部分的代码量并提高可读性。您可能需要牢记这一点。
希望在某种程度上有所帮助!