Search code examples
javaandroidlibgdxinfinite-scroll

Infinite scrolling background on libgdx


I am trying to do an infinite scrolling background on libgdx.The image is scrolling fine in the X-axis, but in the Y-axis the image is split in half like shown in the picture below. How can I get the ground to start at the bottom of the screen? enter image description here

Here is my code

    package com.tashtoons.game.States;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.tashtoons.game.BuckyRun;
import static com.badlogic.gdx.graphics.Texture.TextureWrap.Repeat;



public class PlaySate extends State {
    private Texture bg;
    float sourceX = 0;

    public PlaySate(GameStateManager gsm) {
        super(gsm);
       bg=new Texture("bg.png");
       cam.setToOrtho(false,BuckyRun.WIDTH/2,BuckyRun.HEIGHT/2);
        bg.setWrap(Repeat,Repeat);
    }

    @Override
    protected void handleInput() {

    }

    @Override
    public void update(float dt) {

    }

    @Override
    public void render(SpriteBatch sb) {
        sourceX += 10;
        sb.setProjectionMatrix(cam.combined);
        sb.begin();
        sourceX = (sourceX + Gdx.graphics.getDeltaTime() / 3/4) % bg.getWidth();
        sb.draw(bg, 0, 0, (int) sourceX, 0,BuckyRun.WIDTH, BuckyRun.HEIGHT);
        sb.end();

    }

    @Override
    public void dispose() {

    }

    }

Solution

  • You should pass to cam.setToOrtho() viewport width and height. Also you probably want to correct the code for drawing the texture (left comments in the code):

    public class PlaySate extends State {
        private Texture bg;
        float sourceX = 0;
    
        public PlaySate(GameStateManager gsm) {
            super(gsm);
           bg=new Texture("bg.png");
           cam.setToOrtho(false,BuckyRun.WIDTH,BuckyRun.HEIGHT); // edited this
            bg.setWrap(Repeat,Repeat);
        }
    
    
        @Override
        public void render(SpriteBatch sb) {
            sourceX += 10;
            sb.setProjectionMatrix(cam.combined);
            sb.begin();
    
            // this line doesn't make much sense, you've already incremented sourceX, 
            // "Gdx.graphics.getDeltaTime() / 3/4" especially confuses me
            // why sourceX =% bg.getWidth(); isn't enough?
            sourceX = (sourceX + Gdx.graphics.getDeltaTime() / 3/4) % bg.getWidth();
    
            // you probably want to draw texture in full screen
            sb.draw(bg,
                   // position and size of texture
                   0, 0, WIDTH, HEIGHT, 
                   // srcX, srcY, srcWidth, srcHeight
                   (int) sourceX, 0, bg.getWidth(), bg.getHeight(),
                   // flipX, flipY
                   false, false);
            sb.end();
    
        }
    }
    

    Update

    Instead of these two lines:

    sourceX += 10;
    ...
    sourceX = (sourceX + Gdx.graphics.getDeltaTime() / 3/4) % bg.getWidth();
    ...
    

    there should be only one:

    sourceX = (sourceX + Gdx.graphics.getDeltaTime() * velocity) % bg.getWidth();