在libgdx中无限重复滚动的视差背景

12

我正在制作一个2D横向卷轴的太空射击游戏,需要一个可以无限循环滚动的背景(即瓦片或重复)。我还想实现视差滚动,因此可能有一个最低的背景星云纹理几乎不动,一个更高的包含遥远星星的纹理也几乎不动,以及一个包含靠近星星的纹理移动量较大的最高背景。

我从谷歌上了解到,每个图层的运动量比上面的图层少50%,但是我如何在libgdx中实现这一点?我有一个可以放大和缩小的相机,在物理800x480屏幕上可以显示从128x128像素(飞船)到大片宇宙区域,其中的纹理在其边缘上多次重复。

当相机被完全缩小时,我该如何将较小的纹理(例如512x512)连续地平铺,就好像它是无限平铺的,并且如何将多个这样的纹理分层,将它们保持在适当的结构中(在libgdx api中是否有这样的结构),并随着玩家坐标的变化而移动?我已经查看了javadocs和示例,但找不到类似的问题,如果很显然,请谅解!


目前,玩家输入可以移动玩家的精灵到世界坐标中,而相机则保持在玩家中心。更多信息请参考。 - fundead
4个回答

11

嘿,我也在制作视差背景,试图让它滚动。

存储库中有一个 ParallaxTest.java 文件,可以在此处找到:这里

这个文件是一个独立的类,因此您需要按照自己的方式将其合并到游戏中。您还需要更改控制输入,因为它是连接到触摸屏/鼠标使用的。

这对我起作用了。至于重复的背景,我还没有深入了解,但我认为您只需要基本逻辑,即当离结束屏幕还有一屏时,将前几个屏幕的位置更改为与结束位置对齐。


1
ParallaxTest.java现在位于https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/ParallaxTest.java。 - Max

3
我对视差滚动没有更多的话要说,因为PFG已经说得很清楚了。在测试文件夹下的存储库中确实有一个示例,以及网上的几个解释。我喜欢this one。 背景的问题真的很容易解决。这和其他相关问题可以通过使用模块化代数来解决。我不会详细解释,因为一旦展示出来就非常容易理解。
想象一下,你想在屏幕上显示一个指南针。你有一个代表基本点的1024x16纹理。基本上你只有一条带子。撇开关于实际方向等方面的考虑,你需要渲染它。
例如,您的视口为300x400,并且您想要屏幕上的200px纹理(使其更有趣)。您可以使用单个区域完美地呈现它,直到达到位置(1024-200)= 824。一旦到达此位置,显然没有更多的纹理。但是由于它是一个指南针,很明显一旦到达末端,它必须重新开始。所以这就是答案。另一个纹理区域将起作用。范围825-1023必须由另一个区域表示。第二个区域的大小对于每个值pos>824 && pos<1024都为(1024-pos)
此代码旨在作为指南针的真实示例运行。由于将范围(0-3.6)转换为(0-1024),因此它始终使用相对位置,非常混乱。
spriteBatch.begin();
    if (compassorientation<0)
        compassorientation = (float) (3.6 - compassorientation%3.6);
    else
        compassorientation = (float) (compassorientation %  3.6);
    if ( compassorientation < ((float)(1024-200)/1024*3.6)){
        compass1.setRegion((int)(compassorientation/3.6*1024), 0, 200, 16);
        spriteBatch.draw(compass1, 0, (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), Gdx.graphics.getWidth(), 32 * (float)1.2);

    }
    else if (compassorientation > ((float)(1024-200)/1024*3.6)) {
        compass1.setRegion((int)(compassorientation/3.6*1024), 0, 1024 - (int)(compassorientation/3.6*1024), 16);
        spriteBatch.draw(compass1, 0, (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), compass1.getRegionWidth()/200f * Gdx.graphics.getWidth() , 32 * (float)1.2);
        compass2.setRegion(0, 0, 200 - compass1.getRegionWidth(), 16);
        spriteBatch.draw(compass2, compass1.getRegionWidth()/200f * Gdx.graphics.getWidth() , (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), Gdx.graphics.getWidth() - (compass1.getRegionWidth()/200f * Gdx.graphics.getWidth())  , 32 * (float)1.2);
    } 


    spriteBatch.end();

1
在为对象初始化纹理的位置下方。然后在此处输入以下内容。
YourTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);

其中YourTexture是您想要视差滚动的纹理。

在您的渲染文件中键入此代码。

batch.draw(YourTexture,0, 0, 0 , srcy, Gdx.graphics.getWidth(),     
           Gdx.graphics.getHeight());  
srcy +=10;

它将会给你一个错误,所以创建一个名为srcy的变量。它并不太复杂。
Int srcy

它不会无限重复。 - themorfeus

1
您可以像下面这样使用setWrap函数:
Texture texture = new Texture(Gdx.files.internal("images/background.png"));
texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);

它将重复绘制背景!希望这可以帮助你!


1
你能否在textureRegions上设置换行? - Jente Rosseel
仅供参考:这个包装的是纹理而不是纹理区域,不能与视口缩放一起使用。我认为它还需要一个POT纹理,但可能是错误的。 - RichieHH

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