5

几天前,我想出了如何在 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 即可。

4

4 回答 4

22

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

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

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

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

要从右到左滚动纹理,您所要做的就是逐渐增加 srcX。因此,创建一个在 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);

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

于 2014-05-18T13:37:38.743 回答
10

不要这样,请:

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 如何处理您发布的调用,您可以尝试那个,或者可能使用使用纹理区域的重载并手动设置您的区域。

于 2013-01-31T13:33:24.927 回答
1

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

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

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

于 2013-11-24T00:14:47.060 回答
-1

解决方案

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

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

 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 de 位置,并在下一个渲染循环中重新计算 bck2

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

于 2013-01-30T18:01:17.773 回答