对MathUtils.random()的LibGDX内部调用会干扰生成的随机数序列

时间:2018-06-24 19:17:30

标签: random libgdx box2d

虽然多次使用给定种子的随机数生成器(RNG)(即,每次以相同种子重新调用setSeed()),但我在生成的数字序列上却遇到了一些偏差每次通过。几次把头撞在墙上后,我发现原因是这样的:

box2d的{​​{1}}调用World.createBody(),后者调用LongMap.put(),后者在LongMap.push()循环内调用MathUtils.random()

据我所知,粒子效应也叫while

如果LibGDX在内部使用相同的静态RNG实例并且因此可能弄乱序列,那么我怎么能相信数字序列始终重复出现呢?

我应该如何确切地知道在我的代码之外调用MathUtils.random()的时间和地点?

1 个答案:

答案 0 :(得分:0)

正如@Peter R所指出的那样,一个人可以创建自己的RNG,以保证不会干扰数字序列。

可以使用Java的Random:

import java.util.Random;

private Random random = new Random();

或MathUtils使用的RandomXS128(它扩展了Java的Random,但速度更快):

import com.badlogic.gdx.math.RandomXS128;

private Random random = new RandomXS128();

MathUtils中方便的包装方法(random()签名)也可以根据需要使用(复制到自己的类中),无论是否为静态。例如:

/** Returns a random number between start (inclusive) and end (inclusive). */
public int random (int start, int end) {
    return start + random.nextInt(end - start + 1);
}

/** Returns a random number between start (inclusive) and end (exclusive). */
public float random (float start, float end) {
    return start + random.nextFloat() * (end - start);
}

对于我自己,我仍然对MathUtils为什么提供一个可在内部和外部使用的共享RNG感到困惑,这使得使用RNG带有种子是不安全的,并且在注释中没有提及。

但是,对于不如我那么小巧的人,上述解决方法应该令人满意。