【问题标题】:Scrolling parallax background, infinitely repeated in libgdx滚动视差背景,在 libgdx 中无限重复
【发布时间】:2011-11-22 18:04:13
【问题描述】:

我正在制作一个 2D 横向滚动太空射击类游戏,我需要一个可以无限滚动的背景(它被平铺或重复包裹)。我还想实现视差滚动,所以也许有一个最低的背景星云纹理几乎不移动,一个较高的背景包含几乎不移动的遥远恒星,而最高的背景包含移动很多的近距离恒星。

我从 google 看到,我会让每一层的移动量比它上面的层少 50%,但是如何在 libgdx 中实现呢?我有一个可以放大和缩小的相机,在 800x480 的物理屏幕上可以显示任何东西,从 128x128 像素(一艘船)到巨大的空间区域,其边缘有多次包裹的纹理。

我如何连续包裹一个较小的纹理(比如 512x512),就好像它被无限平铺(当相机缩小时),然后我如何分层多个这样的纹理,将它们放在一个合适的结构中(在 libgdx api 中有一个吗?)并随着玩家坐标的变化移动它们?我查看了 javadocs 和示例,但找不到类似的问题,如果很明显,请道歉!

【问题讨论】:

  • 更多信息,现在玩家输入会在世界坐标周围移动玩家的精灵,并且相机仍然以玩家为中心。

标签: scroll 2d textures libgdx parallax


【解决方案1】:

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

仓库中有一个ParallaxTest.java,可以找到here

这个文件是一个独立的类,所以你需要将它合并到你的游戏中。并且您将需要更改控制输入,因为它已连接到使用触摸屏/鼠标。

这对我有用。至于重复的bg,我还没有走那么远,但我认为你只需要基本的逻辑就可以了,离最后一个屏幕,改变前几个屏幕的位置到最后对齐。

【讨论】:

【解决方案2】:

关于视差滚动,我没有比 PFG 已经做过的多说的了。在测试文件夹下的存储库中确实有一个示例,并在网络上提供了一些解释。我喜欢this one。 有背景的事情真的很容易解决。这个和其他相关问题可以通过使用模代数来解决。我不会详细介绍,因为一旦显示就很容易理解。

假设您想在屏幕上显示指南针。你有一个代表基点的纹理 1024x16。基本上你所拥有的只是一条带子。抛开关于真实方向等的考虑,你必须渲染它。

例如,您的视口为 300x400,并且您希望屏幕上的纹理为 200 像素(使其更有趣)。您可以使用单个区域完美地渲染它,直到到达位置 (1024-200) = 824。一旦您处于该位置,显然就不再有纹理了。但既然它是一个指南针,很明显,一旦你到达它的尽头,它必须重新开始。所以这就是答案。另一个纹理区域可以解决问题。范围 825-1023 必须由另一个区域表示。对于每个值 pos>824 && pos,第二个区域的大小将为 (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();

【讨论】:

    【解决方案3】:

    你可以像下面这样使用 setWrap 函数:

    Texture texture = new Texture(Gdx.files.internal("images/background.png"));
    texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
    

    它会重复绘制背景!希望对您有所帮助!

    【讨论】:

    • 你也可以在textureRegions上设置换行吗?
    • 仅供参考:这包含纹理而不是纹理区域,并且不适用于视口缩放。我相信它还需要 POT 纹理,但可能会出错。
    【解决方案4】:

    在您为对象初始化纹理的位置下方。然后在这个类型的下面

    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
    

    【讨论】:

    • 它不会无限重复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2017-05-14
    • 1970-01-01
    相关资源
    最近更新 更多