Saurabh
Saurabh

Reputation: 308

How to infinitely repeat background in Libgdx?

I am using this class :

import com.badlogic.gdx.graphics.g2d.TextureRegion;


public class ParallaxLayer {

//  the Texture sitting on this layer

public TextureRegion region;

/**
 * how much shall this layer (in percent) be moved if the whole background is moved
 * 0.5f is half as fast as the speed
 * 2.0f is twice the speed
 */
float ratioX, ratioY;

/**
 * current position
 */
float positionX, positionY;

/**
 * 
 * @param pRegion
 * @param pRatioX
 * @param pRatioY
 */
public ParallaxLayer(TextureRegion pRegion, float pRatioX, float pRatioY) {
    region = pRegion;
    ratioX = pRatioX;
    ratioY = pRatioY;
}

/**
 * move this layer
 * @param pDelta
 */
protected void moveX(float pDelta) {
    positionX += pDelta * ratioX;
}

/**
 * move this layer
 * @param pDelta
 */
protected void moveY(float pDelta) {
    positionY += pDelta * ratioY;
}

}

and this class :

   import com.badlogic.gdx.graphics.g2d.TextureRegion;


public class ParallaxLayer {
/**
 * the Texture sitting on this layer
 */
public TextureRegion region;

/**
 * how much shall this layer (in percent) be moved if the whole background is moved
 * 0.5f is half as fast as the speed
 * 2.0f is twice the speed
 */
float ratioX, ratioY;

/**
 * current position
 */
float positionX, positionY;

/**
 * 
 * @param pRegion
 * @param pRatioX
 * @param pRatioY
 */
public ParallaxLayer(TextureRegion pRegion, float pRatioX, float pRatioY) {
    region = pRegion;
    ratioX = pRatioX;
    ratioY = pRatioY;
}

/**
 * move this layer
 * @param pDelta
 */
protected void moveX(float pDelta) {
    positionX += pDelta * ratioX;
}

/**
 * move this layer
 * @param pDelta
 */
protected void moveY(float pDelta) {
    positionY += pDelta * ratioY;
}

}

And in main class :

 camera=new OrthographicCamera(400,240);
camera.position.x=200;
camera.position.y=120;
camera.update();
batch=new SpriteBatch();

layer1=atlas.findRegion("layer1");
layer2=atlas.findRegion("layer2");
layer3=atlas.findRegion("layer3");
ParallaxLayer l1=new ParallaxLayer(layer1,0,0);
ParallaxLayer l2=new ParallaxLayer(layer2,0.5f,0);
ParallaxLayer l3=new ParallaxLayer(layer3,1,0);
ParallaxLayer[] layers={l1,l2,l3};
background=new ParallaxBackground(layers, camera,batch);

// [...] in render
background.moveX(30*delta); // move to the right to show the effect

background.render();

to achieve parallax scrolling effect but i want infinite scrolling but unable to get it. I tried doing this in ParallaxBackground class under for loop but repeats only three time.

  posXbg1L1 = layer.positionX;

        posXbg2L1 = posXbg1L1 - layer.region.getRegionWidth();


       if (camera.position.x <= posXbg2L1 - camera.viewportWidth / 2) {
           // Gdx.app.log("TAG", camera.position.x + ":" + posXbg2L1 + camera.viewportWidth / 2);
            posXbg1L1 = posXbg2L1;

        }

        batch.draw(layer.region, -camera.viewportWidth / 2
                - posXbg1L1, -camera.viewportHeight / 2
                - layer.positionY);

        batch.draw(layer.region, -camera.viewportWidth / 2
                - posXbg2L1, -camera.viewportHeight / 2
                - layer.positionY);

    }

Any psuedocode/code will be helpful.

Upvotes: 0

Views: 378

Answers (1)

Matthew Tory
Matthew Tory

Reputation: 1306

You could try something like this:

TextureRegion[] backgrounds = [...your array of background textures...];
float[] parallax = {...your parallax coefficients...}; //For example {0.2f, 0.1f}

public void drawLayers(Batch batch, OrthographicCamera camera) {
    batch.setColor(Color.WHITE);
    for(int b = backgrounds.length - 1; b >= 0; b--) {
        TextureRegion background = backgrounds[b];

        if(background != null) {
            float x = (camera.position.x - camera.viewportWidth / 2f * camera.zoom);
            float y = camera.position.y - camera.viewportHeight / 2f * camera.zoom + camera.viewportHeight / 15f * camera.zoom;

            float rWidth = camera.viewportWidth * 1.5f * camera.zoom;
            float rHeight = (rWidth / background.getRegionWidth()) * background.getRegionHeight();

            drawParallaxLayer(batch, background, parallax[b], x, y, rWidth, rHeight);
        }
    }
}

public static void drawParallaxLayer(Batch batch, TextureRegion region, float parallax, float x, float y, float width, float height) {
    for(int j = 0; j < 3; j++) {
        batch.draw(region, x + (j * width) - ((x * parallax) % width) - (width / 2f), y, width, height);
    }
}

You might have to adjust some of the position/width/height values in the drawLayers function, but the real magic happens in drawParallaxLayer - which should be able to stay the same.

Upvotes: 1

Related Questions