【问题标题】:LibGdx How to repeat background?LibGdx 如何重复背景?
【发布时间】:2013-01-30 12:13:59
【问题描述】:

几天前,我想出了如何在 LibGdx 中进行一些滚动。现在我正在尝试做一些相关的事情。我想重复背景。我的滚动跟随一艘船(是一个 s[ace 船游戏)。在背景中有一张作为纹理加载的空间照片。当船到达背景的尽头时,它继续前进,没有背景了。我已经阅读了有关 wrap 的内容,但我并不真正了解它是如何工作的。我做到了:

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

然后,在我的渲染方法中

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

当然不行,它只会画一次背景。我不知道如何使这种包装方法起作用。有什么帮助吗?

解决方案

我想通了。这不是一个很好的代码,但它可以工作。

首先我声明两个具有相同图像的纹理

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

我还声明了两个这样的变量来指定每个bck位置的X值

 int posXBck1=0,posXBck2=0;

然后我在 Render() 中使用它

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

地点:

ANCHODEFONDO 是我背景的宽度

Cam 是 OtrhoCam。

所以我说如果凸轮在 bck2 中(这意味着你再也看不到 bck1)它会改变位置,给出 bck2 的 bck1 位置,并在下一个渲染循环中重新计算 bck2

然后在您的渲染模式下绘制两个 bck。

【问题讨论】:

  • 如果您找到了解决方案,请将其作为答案发布。

标签: java libgdx


【解决方案1】:

就像 Teitus 所说,永远不要多次加载纹理!无论如何,你在正确的轨道上使用包装器:

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

现在您可以只对源位置使用 draw 方法。源位置是您选择在纹理上绘制的区域。

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

要从右到左滚动你的纹理,你所要做的就是逐渐增加 srcX。所以在更新/渲染方法中创建一个递增的 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);

因为您正在包裹纹理,所以它会包裹/循环并无限期地滚动。如果游戏运行很长时间,sourceX int 可能会出现问题,因为 int 只能容纳 2147483647。这需要一段时间,但您可以通过在每次数字超过总图像宽度时减去图像宽度来修复它.

【讨论】:

    【解决方案2】:

    请不要这样:

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

    这将加载你的大背景纹理两次。这完全是浪费。如果您想保留您的解决方案,请至少这样做:

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

    关于纹理包裹。如果你的纹理是 500px 宽,并且你绘制了一个 500px 的精灵,你不会看到任何重复。如果你想让它重复 2 次,用 0-2 纹理坐标绘制 1000px 宽。 我不确定 spriteBatch 如何处理您发布的调用,您可以尝试那个,或者可能使用使用纹理区域的重载并手动设置您的区域。

    【讨论】:

    • 你的代码会在bck2中给出bck1的指针,如果你移动bck2它会移动bck1。
    • 如果您可以“移动”纹理(请参阅 api,它没有位置/变换),那将是正确的。这由精灵批处理处理 - 请注意,位置是通过参数传递给精灵批处理的。
    • 注意 - 如果使用 TextureRegions 绘图,您应该另外将 TextureRegion 的宽度/高度设置为较大的值以实现所需的重复行为。
    【解决方案3】:

    我看到这是一个很老的问题,但我认为有一种更简单的方法来完成背景滚动。只需使用 Sprite 类。这是我用于从右到左滚动的分层背景图像的 sn-p。

    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);
        }
      }
    }
    

    然后你可以像这样使用相同的纹理或一系列纹理:

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

    我在代码中随机更改背景重复部分,并在它们离开屏幕时制作新的或重置现有的集合。所有层都进入一个池,并在需要新层时随机抽取。

    【讨论】:

      【解决方案4】:

      解决方案

      我想通了。这不是一个很好的代码,但它可以工作。

      首先我声明两个具有相同图像的纹理

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

      我还声明了两个这样的变量来指定每个bck位置的X值

       int posXBck1=0,posXBck2=0;
      

      然后我在 Render() 中使用它

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

      地点:

      ANCHODEFONDO 是我背景的宽度

      Cam 是 OtrhoCam。

      所以我说如果凸轮在 bck2 中(这意味着你再也看不到 bck1)它会改变位置,给出 bck2 的 bck1 位置,并在下一个渲染循环中重新计算 bck2

      然后在你的 render() 中绘制两个 bck

      【讨论】:

      • 我认为只有一次纹理,并从同一个纹理中设置两个不同的纹理区域就足够了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 2014-10-17
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多