简体   繁体   English

LibGdx如何重复背景?

[英]LibGdx How to repeat background?

Few days ago I figured out how to do some scrolling in LibGdx. 几天前我想出了如何在LibGdx中进行一些滚动。 Now I'm triying to do something related. 现在我正在试图做一些相关的事情。 I want to repeat the background. 我想重复背景。 My scrolling follows a ship (Is an s[ace ship game). 我的滚动跟随一艘船(是一个s [王牌船游戏]。 In the background there is a space photo loaded as a Texture. 在背景中有一张空间照片作为纹理加载。 When the ship reach the end of the backgorund, It keeps going and there's no background anymore. 当船到达backgorund的末端时,它继续前进并且不再有背景。 I have read about wrap but I don't really understand How It works. 我读过关于包装的内容,但我并不真正理解它是如何工作的。 I did that: 我这样做了:

    px=new Pixmap(Gdx.files.internal("fondo.jpg"));
    background=new Texture(px);
    background.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);

And then, in my render method 然后,在我的渲染方法中

spriteBatch.begin();
    spriteBatch.draw(background,0,0,500,50);
    drawShip();
spriteBatch.end();

Of course It doesn't work, It only draws the background once. 当然它不起作用,它只绘制一次背景。 I don't know how make this wrap method work. 我不知道如何使这个包装方法工作。 Any help? 有帮助吗?

SOLUTION

I figured It out. 我想到了。 It's not a nice code but It works. 这不是一个很好的代码,但它的工作原理。

First I declare two Textures with the same image 首先,我用相同的图像声明两个纹理

 bck1=new Texture(Gdx.files.internal("fondo.jpg"));
 bck2=new Texture(Gdx.files.internal("fondo.jpg"));

Also I declare two variables like this to specify the X value of the position of each bck 我还声明了两个这样的变量来指定每个bck位置的X值

 int posXBck1=0,posXBck2=0;

Then I use that in Render() 然后我在Render()中使用它

 public void calculoPosicionFondos(){
    posXBck2=posXBck1+ANCHODEFONDO;
    if(cam.position.x>=posXBck2+cam.viewportWidth/2){
        posXBck1=posXBck2;
    }
}

Where: 哪里:

ANCHODEFONDO is the width of my background ANCHODEFONDO是我背景的宽度

Cam is an OtrhoCam. Cam是OtrhoCam。

So I said that if the cam is in bck2 (wich means that you can't see bck1 anymore) It change positions, giving bck1 de position of bck2 and, in the next render loop, recalculating bck2 所以我说如果凸轮在bck2中(这意味着你不能再看到bck1)它改变位置,给出bck2 de bck2的位置,并在下一个渲染循环中重新计算bck2

Then just paint both bck in your render mode. 然后在渲染模式下绘制两个bck。

Like Teitus said, do not load your texture multiple times , ever! 就像Teitus说的那样, 不要多次加载纹理 Anyway, you where on the right track with the wrapper: 无论如何,你在包装纸的正确轨道上:

texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);

Now you can just use the draw method with the source location. 现在您可以将draw方法与源位置一起使用。 The source location is the area you choose to draw on the texture. 源位置是您选择在纹理上绘制的区域。

batch.draw(texture, x, y, srcX, srcY, srcWidth, srcHeight)

To scroll your texture from right to left all you have to do is increase srcX incrementally. 要从右向左滚动纹理,您所要做的就是逐步增加srcX。 So create a int that increments in the update/render method. 因此,创建一个在update / render方法中递增的int。

int sourceX = 0;

//render() method

//Increment the variable where to draw from on the image.
sourceX += 10;

//Simply draw it using that variable in the srcX.    
batch.draw(YourTexture, 0, 0, sourceX, 0, screenWidth, screenHeight);

Because you are wrapping the texture it will wrap/loop and scroll indefinitely. 因为你正在包装纹理,它将包装/循环并无限滚动。 There might be a issue with the sourceX int if the game runs for a very long time because a int can only hold 2147483647. It takes a while but you can fix it by subtracting the image width each time the number goes over the total image width. 如果游戏运行了很长时间,那么sourceX int可能会出现问题,因为int只能容纳2147483647.这需要一段时间但你可以通过在每次数字超过总图像宽度时减去图像宽度来修复它。

Don't to this, please: 请不要这样:

bck1=new Texture(Gdx.files.internal("fondo.jpg"));
bck2=new Texture(Gdx.files.internal("fondo.jpg"));

That will load your big background texture twice. 这将加载你的大背景纹理两次。 That's a complete waste. 这完全是浪费。 If you want to keep your solution at least do: 如果你想保持你的解决方案至少做:

bck1=new Texture(Gdx.files.internal("fondo.jpg"));
bck2=bkg1;

Regarding the texture Wrapping. 关于纹理包装。 If your texture is 500px wide, and you draw a 500px sprite, you won't see any repetition. 如果您的纹理宽度为500px,并且您绘制了500px精灵,则不会看到任何重复。 If you want it repeated 2 times, draw it 1000px wide with 0-2 texture coordinates. 如果你想重复2次,用0-2纹理坐标绘制1000px宽。 I'm not sure how spriteBatch handles the call you posted, you could try that one, or may be use the overload that uses a texture region and set your region manually. 我不确定spriteBatch如何处理您发布的调用,您可以尝试使用该调用,或者可以使用使用纹理区域的重载并手动设置您的区域。

I see this is a pretty old question, but I think there is an easier way to accomplish background scrolling. 我认为这是一个非常古老的问题,但我认为有一种更简单的方法来完成背景滚动。 Just use the Sprite class. 只需使用Sprite类。 Here is a snippet I use for layered background images that scroll from right to left. 这是我用于从右到左滚动的分层背景图像的片段。

public class LevelLayer 
{
    public float speedScalar = 1;

    private List<Sprite> backgroundSprites = new ArrayList<Sprite>();

    public LevelLayer()
    {

    }

    public void addSpriteLayer(Texture texture, float startingPointX, float y, int repeats)
    {
        for (int k = 0; k < repeats; k++)
        {
          Sprite s = new Sprite(texture);
          s.setX(startingPointX + (k*texture.getWidth()));
          s.setY(y);

          backgroundSprites.add(s);
        }
    }

  public void render(SpriteBatch spriteBatch, float speed)  
  { 
    for (Sprite s : backgroundSprites)
    {
        float delta = s.getX() - (speed * speedScalar);
        s.setX(delta);

        s.draw(spriteBatch);
    }
  }
}

Then you can use the same texture or series of textures like so: 然后你可以使用相同的纹理或一系列纹理,如下所示:

someLayer.addSpriteLayer(sideWalkTexture1, 0, 0, 15);
someLayer.addSpriteLayer(sideWalkTexture2, 15 * sideWalkTexture1.getWidth(), 0, 7);

I change background repeating sections randomly in code and make new ones or reset existing sets when they go off screen. 我在代码中随机更改背景重复部分并创建新部分或在屏幕关闭时重置现有集合。 All the layers go to a pool and get pulled randomly when a new one is needed. 所有图层都会进入游泳池,并在需要新图层时随机抽取。

SOLUTION

I figured It out. 我想到了。 It's not a nice code but It works. 这不是一个很好的代码,但它的工作原理。

First I declare two Textures with the same image 首先,我用相同的图像声明两个纹理

 bck1=new Texture(Gdx.files.internal("fondo.jpg"));
 bck2=new Texture(Gdx.files.internal("fondo.jpg"));

Also I declare two variables like this to specify the X value of the position of each bck 我还声明了两个这样的变量来指定每个bck位置的X值

 int posXBck1=0,posXBck2=0;

Then I use that in Render() 然后我在Render()中使用它

 public void calculoPosicionFondos(){
    posXBck2=posXBck1+ANCHODEFONDO;
    if(cam.position.x>=posXBck2+cam.viewportWidth/2){
        posXBck1=posXBck2;
    }
}

Where: 哪里:

ANCHODEFONDO is the width of my background ANCHODEFONDO是我背景的宽度

Cam is an OtrhoCam. Cam是OtrhoCam。

So I said that if the cam is in bck2 (wich means that you can't see bck1 anymore) It change positions, giving bck1 de position of bck2 and, in the next render loop, recalculating bck2 所以我说如果凸轮在bck2中(这意味着你不能再看到bck1)它改变位置,给出bck2 de bck2的位置,并在下一个渲染循环中重新计算bck2

Then just draw both bck in your render() 然后在你的渲染中绘制两个bck()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM