我将制作一个完全由程序生成的太空/交易/战斗游戏.但是,我知道将整个星系的所有细节存储在记忆中是不可能的.因此,我一直认为我可以使用种子来生成太阳系,并且从太阳系中,您可以使用跳跃门来前往其他太阳系.问题是,如果我从起始太阳系跳到另一个太阳系,我需要能够回到具有完全相同特征(行星,小行星等)的完全相同的起始太阳系.
基本上,我需要能够从一个数字生成整个星系.从生成一个太阳系的那个数字开始,我需要能够生成所有其他太阳系,这些太阳系从第一个和所有与之相连的太阳系连接起来,依此类推.如果我回到它们,每个太阳系必须保持完全相同的特征.此外,每个太阳系的链接数量可以是随机的,也可以是固定的,您的选择.随机会更好.
如果你觉得自己很勇敢,那么你可能会比看看伊恩贝尔为原版精英版做的更糟糕
查看Gamasutra上的这个系列:
一个实时程序宇宙,前四个链接
此外,这:无限宇宙的算法
这是我理解的基本想法.假设你已经到达了星系统#42,你需要找出其中的内容.它有nplanets
行星 - 0到10之间的数字,比如:
>>> star_system = 42 >>> nplanets = hash('nplanets%d' % star_system) % (10 + 1) >>> nplanets 4
好吧,那么在行星#2上,在游戏开始时有多少空间站在轨道上?找到0到3之间的数字:
>>> planet = 2 >>> nstations = hash('nstations%d/%d' % (star_system, planet)) % (3 + 1) >>> nstations 1
等等.这些数字都是指数的散列函数(星系统#42,行星#2,在这种情况下),减少到适当的范围.由于散列函数是确定性的但是"随机",因此每次都是相同的,但对玩家来说是随机的.
当然,散列具有长序列(例如'nstations')的字符串并不是最快速的方法,但它显示了这个想法.
看看最初的蠕虫游戏.我认为它声称有大约40亿个可能的水平.每个级别都是基于可能包含20个字符的短种子字符串生成的.这决定了
关卡的主题(北极,森林等......)
景观的形状
地面的滑溜
预建水平细节的位置(雪人,岩石......)
你的蠕虫,地雷和武器箱子的安置.
如果您喜欢某个级别,您可以记下种子字符串,并使用它在以后重新生成相同的级别.
这是一个非常复杂但确定性的函数的示例,具有单个输入参数.我认为这是您需要的基本概念.
不能只是SHA1星系ID,EG:
Sha1(1) = 356a192b7913b04c54574d18c28d46e6395428ab
Sha1(2) = da4b9237bacccdf19c0760cab7aec4a8359010b0
Sha1(3) = 77de68daecd823babbb58edb1c8e14d7106e83bb
然后你可以分割代码,IE:
356a da4b 77de
你需要某种字符串编号算法,一个简单的方法是获取每个非数字字符的ASCII码,然后将它们全部加在一起或其他东西.
那么现在我们知道星系中有多少行星,星系x,y,z尺寸怎么样?
与上述原理相同,将代码转换为大数.进行一些敏感性检查,你不需要一个10英里×10英里×10英里的星系,其中有20万个行星.有一些加权算法,比如最小尺寸是行星数×10000.您需要使用数字来确保范围全部兼容,并且哈希中选定的字符实际上为您提供了合理的范围.
或者,您可以使用随机数在星系的最小和最大尺寸之间选择一个数字,但使用恒定的RNG种子,例如星系ID!这样,对于观察者来说,星系大小基本上是"随机的",但每次都是相同的.
这是获取宇宙属性的一种方法,但是行星属性呢?喜欢人口和其他东西?
如果你有拥有20,000个行星的Galaxy 1,你可以:
Sha1('1:340') = bc02ab36f163baee2a04cebaed8b141505cc26b5
也就是说,星系一,行星340.然后,您可以随心所欲地拼接该代码.使用哈希的好处是每个星球都应该有一个完全唯一的代码.
我认为值得注意的是
为同一输入产生相同随机输出的输出的发生器称为伪随机数发生器,"PRNG".通常,您在一开始就给它一个"种子"输入数字,然后从中拉出随机数,在没有进一步输入的情况下调用它.注意:您不能"返回"前面的数字,至少在没有开始时也是如此.
用坐标作为每个调用的输入调用的类似PRNG的函数通常是"噪声"函数.在这里你没有"不能回头"的问题 - 只需再次使用"早期"输入.噪声函数使用PRNG(作为后端;或者至少它可以),它仍然可以在一开始播种,因此您不会丢失"超出一个数字"的特征.
虽然你可以使用PRNG并且每次将星系坐标组合成"种子",但你最多只能获得"白噪声",没有其他属性.噪音功能更适合这项工作,因为它可以选择甚至调整,以给你平铺/平滑/螺旋状外观/等.结果.例如,搜索使用perlin噪声制作的纹理图像.我希望你能看到,你可以用相同的噪声函数创建数千个随机云,但通过根据需要调整噪声函数(不仅仅是种子或坐标),你可能会得到熔岩或星系.尽管如此,调整它可能并非易事.
每个调用的输入坐标数决定了噪声函数的维数,因此对于二维图(或纹理等),您可以使用二维噪声函数.然后你每次都称它为noise2d(x,y).
在你的情况下,我会尝试一个三维单面噪声函数(simplex来自perlin噪声的作者,建议更好).
然后每个星系坐标 - 三元组给出一个结果数.接下来的决定是:数字代表什么?为了充分利用单纯噪声的平滑特征,我将较低的数字映射到更多的太阳系,将更高的数字映射到质量更大的系统.或者,更好的是,对于每个系统,使用子坐标多次调用单纯形噪声.中等大小的结果数字则是行星,小数字是真空或小行星.大数星等
该主题不活跃且已经过时,但搜索可能会像我一样在这里结束.