对于我正在制作的游戏,我想实现一个滚动的星空。到目前为止,所有游戏都是从OpenGL原语中提取出来的,我想继续这个并且gl_points似乎是合适的。
我正在使用pyglet(python)并知道我可以实现这一点存储一大堆的位置或点更新它们并手动移动它们但我希望有一个更整洁的替代方案。
修改 回答伊恩马利特 我想我想问的是,如果我生成一堆点,是否有某种方法可以将它们放在某种表面或缓冲区上并在后台滚动它。
另外至于我在这个阶段想要产生什么样的星场所有我想要一个简单的单层进行自上而下的游戏,几乎就像你在小行星中所拥有的那样
答案 0 :(得分:4)
(特色:视差滚动)
基本配方是:
生成N个随机点(X,Y)和一个“Z”值(每个点数为0.5 ... 2)
翻译每个点的位置:(X,Y) += scrollXY * Z
这是棘手的部分。 每个点都有不同的Z值,因此它们以不同的速度滚动。这称为“视差滚动”并产生惊人的效果。
包裹点数(以屏幕尺寸为模)。
每帧使用相同的种子会给你一个随机的星域模式,但每帧都是持久的(只有滚动值改变)。
可以轻松修改此算法,以便您永远不必在内存中实际存储所有N个位置。您只需要一个生成器,它为您提供随机基(X,Y)坐标(和深度),并由常数值和一些星号进行播种。
伪代码:
for (int i=0; i<1000; ++i) {
RandomGenerator rnd;
rnd.seed(SomeConstantSeed + i*10293);
// determine i-th star's position
var basePosition = vec2(rnd.next(800), rnd.next(600));
var depth = rnd.next(0.5, 2);
// parallax scrolling and wrapping
var realPosition = basePosition + scrollXY * depth;
var wrappedPosition = realPosition modulo vec2(800, 600);
// these are our coordinates! let's draw
renderStar(wrappedPosition);
}
在这里,每个星都是按需生成的,我们不必在帧之间保持其内存值。随机生成器种子必须是恒定的,以便每帧生成相同(但动画)的星域。
您可以使用相同的技术为每颗星分配不同的随机(但持久)颜色。
最简单有效的方法是在顶点着色器中动态生成位置。
在VBO中准备星形几何体。它可以是你想要的任何东西:一个顶点(用于点 - 精灵),一个纹理四边形,任何东西。
使用glDrawArraysInstanced
渲染,其中primcount
是您想要的星数
在您的顶点着色器中,从上面的伪代码实现循环体,用gl_InstanceID
替换i
。然后通过滚动值(作为uniform vec2
变量传递)更改每个顶点的输入XY屏幕位置(VS中的属性变量),如上所述。
一些脚注:
答案 1 :(得分:1)
你能澄清什么样的星空吗? 2D滚动(用于侧面或顶部滚动游戏,可能有不同的图层)或3D(就像在一个不可思议的快速飞船中真正飞过星空一样)?
在前者中,纹理(或混合添加的纹理层)可能是最干净和最快速的方法。 [编辑:纹理是迄今为止最好的方法,但如果你真的不想使用纹理,你可以做以下,这是下一个最好的事情:
在后者中,我可以想到一些聪明的算法,但我建议只使用原始点(如果你感觉很奇怪,那就是点精灵);如果将GPU放在静态VBO或显示列表中,GPU可以处理此问题。如果你的积分很小,你可以一次扔掉几千,但没有任何明显的性能损失。