巧妙绘制星空的方法

14

我正在开发一款游戏,并遇到了一个相当有趣的问题:如何巧妙地绘制星空。

这是一个2D游戏,因此动作可以在X和Y方向上滚动。此外,我们可以调整比例以显示更多或更少的游戏区域。我还希望星空具有虚假的视差效果,以给人深度印象。

现在我正在传统的方式中完成这个问题,即拥有一个大型星球数组,每个星球都由“深度”系数标记。为了绘制,我根据相机位置乘以“深度”系数来平移每颗星球,所以有些星球移动很多,有些移动很少。这一切都运行得很好,但是当相机移动太远或缩放太多时,我就会遇到问题,因为我的数组中只有有限数量的星球。这样做将有效,但涉及到很多代码和特殊情况,让人感到不太优雅。

这触犯了我的优雅感。一定有更好的方法实现这个目标。

我考虑过程序生成星球,这样我就可以拥有无限数量的星球:例如通过使用固定种子和PRNG来确定坐标。我需要将天空分成瓦片,通过散列瓦片坐标来生成种子,然后在每个瓦片上绘制100颗星球。这样可以在所有方向上无限扩展我的星空,同时仅需要考虑可见的瓷砖,但是这不能与“深度”系数配合使用,因为这会使一些星球超出它们的瓷砖范围。使用此算法可以只使用多层非视差星座,但是这让我感觉像是作弊。

当然,我需要在每个帧中完成所有这些操作,所以它必须很快。

你们认为如何呢?


3
试试访问http://gamedev.stackexchange.com,那里可能有更多关于这类问题的经验。 - Björn Pollex
我甚至不知道那个存在;谢谢。任何管理员,随意将问题移动到那里... - David Given
无论你想出什么解决方案,如果你需要更好的性能,就将你的代码转换为使用整数定点数而不是浮点数。 - The Unix Janitor
1
有趣的问题,我认为它应该在SO上发布。 - Robert Karl
1
星星不应该引起视差,除非你的游戏对象移动得比光速快得多。当然,如果你认为这很酷,就去做吧。 - jprete
5个回答

2

有几层星星。

对于每一层,使用一个种子随机数生成器(或者只是一个数组)来生成星星之间的空格数量(泊松分布,如果你想要更精确)。你希望星星非常稀疏,因此空格通常会超过整个行。后面的层比前面的层更密集。

使用这个方法为自己创建几个瓷砖,每个瓷砖宽两个屏幕。通过跟踪每层“第一个”星星的位置来滚动星空。

玩家不会注意到平铺,因为你为每层使用不同的滚动速度,特别是如果你使用几个相当稀疏的层。


1

由于背景中的星星移动速度不如前景中的快,因此您可以为背景制作多层瓷砖,并在有时间时将它们替换为单层瓷砖。哦,那么背景层中的重复图案怎么样?这可能允许您预先生成所有背景瓷砖 - 您仍然可以在高度上移动它们并叠加多个具有随机偏移量的瓷砖以使其看起来随机。


1

将星场在X和Y轴上进行包装有什么问题吗?由于深度的不同,包装距离应该取决于深度,但您可以这样做。每个记录的星星在(x,y,depth)处应出现在所有点

[x + j * S * depth,y + k * S * depth]

对于所有整数jkS是一个环绕参数。如果S为1,则立即发生环绕,并且始终会在某个地方显示所有星星。如果S更高,则不会立即发生环绕,并且一些星星会显示在屏幕外。您可能需要使S足够大,以确保在最大缩放时没有重复。


0

每一帧,将星星渲染在一个单独的位图/层上。它们只是点,因此使用任何具有多个层的算法会更快。

现在,您需要一个填充有有限数量星星的无限二维网格的三维盒子。对于每个盒子,您可以使用其网格坐标定义一个单独的RANDOM_SEED值。每个盒子中的星星可以即时生成。

记得在缩放时纠正透视:每个3D盒子都有一个近矩形(前面)和一个远矩形。当远矩形或近矩形在您的视野中缩小时,您将看到相邻盒子中更多的星星。

您的远矩形不应小于近矩形宽度的一半,否则可能会出现问题:您可能必须扫描大量超出边界的星星列表。您可以通过其他大小和深度的附加三维盒子的额外二维网格来实现远矩形后面的星星。


0
为什么不将星场3D盒子的坐标组合起来形成随机数种子呢?如果你想要生成不同的宇宙,可以使用全局“调整”。这样,你就不需要跟踪那些你看不到的盒子,因为它们的内容是由它们的位置固定的。

1
这个问题讨论如何在视口移动时生成具有视差效果的“星空”背景。不确定这个答案是否解决了这个问题。 - TheCodeArtist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接