序列化java.util.Random

时间:2015-04-10 01:28:48

标签: java random

我正在开发一个简单的小游戏(主要是为了了解Java 8和JavaFX中的新功能)。我拥有的一个功能是能够为游戏的随机数生成器播种,这样你就可以在不同的系统上玩朋友大致相同的游戏(认为 Minecraft 地图或 Isaac的绑定游戏)。

我想添加保存游戏的功能,以便稍后恢复。查看java.util.Random类的文档后,我找不到获取随机数生成器当前种子的方法。我保存游戏后恢复随机数生成器的唯一方法是在保存时通过反射访问种子并使用它,或者在加载时播种初始种子,然后调用nextInt()一遍又一遍,直到我们将随机数生成器向前滚动到足以保存游戏之前的位置。

1 个答案:

答案 0 :(得分:5)

首先,正如@ user2357112指出的那样,Random实现了Serializable,并通过编写seed字段(以及nextNextGaussian和{{1}来实现字段)。你尝试过简单序列化吗?这应该“正常工作”。其他序列化器,如Gson,也可以工作。 haveNextNextGaussian返回一个相同的对象。

您不一定需要相同的 gson.fromJson(gson.toJson(r), Random.class);实例,只需要一致的实例。您只需调用Random并将该值作为nextLong()或其他任何内容写入您的保存文件。然后只使用该种子初始化random_seed实例,现在从该文件加载的所有运行都将表现相同。如果您愿意,您甚至可以将当前正在运行的游戏中的Random实例重置为相同的种子。

另一方面,如果你随机生成地图或其他看似不变的内容并希望它在加载之间保持不变,我认为你最好只是在开始时简化种子Random,并像你描述的那样保存那个值。为了节省计算,您可以在小于整个级别的块中执行此操作。例如,将每个级别拆分为10个,并为每个级别使用(并保存)不同的种子。然后你只需要生成用户现在的部分,而不是他们已经越过的部分。如果你只是像你建议的那样保存当前状态,那么用户就无法在地图中倒退(特别是对于你的游戏来说这可能不是问题,但一般来说这不是一个好习惯)。


UX警告:保存游戏的随机性似乎可能过度设计。作为用户,我通常不希望保存文件保持随机性。事实上,有时玩家会利用这一点,例如,如果他们在保存后立即死于随机遭遇,重新加载游戏并不会立即让他们重新陷入相同的遭遇。我会考虑让你的游戏Random无法播种,让每个游戏都有点独特。