Edd
Edd

Reputation: 11

libgdx : Spritebatch not rendering until resize

Long story short: my spritebatch doesn't render anything until I resize the window (even by 1 pixel).

Long story: I'm following the Brent Aureli's tutorial on how to create the game Flappy Bird: Every game state (title menu, playing screen, pause screen etc) is a State. The States are managed in the form of a Stack<State> by the GameStateManager. The GameStateManager calls the classic loop methods of the State situated at the top of the stack.

My problem: the first State (whichever) that I push in the empty Stack renders just fine. However, if I pop/push to another state, it doesn't render anymore (I get glClearColor screen). If I just push another state, doesn't render either until I click at the bottom corner of my game window and resize. Then everything renders again.

I downloaded libgdx and Android sdk approximatively 4 weeks ago. I'm really confused.

Here's the code:

public class MyGame extends ApplicationAdapter {
    public static final int V_WIDTH = 800;
    public static final int V_HEIGHT = 480;
    public static final String title = "MyGame";

    private GameStateManager gsm;
    private SpriteBatch sb;
    @Override
    public void create () {
        
        sb = new SpriteBatch();
        gsm = new GameStateManager();
        Gdx.gl.glClearColor(0,1,0,1);
        gsm.push(new FooState(gsm));


    }

    @Override
    public void render () {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        gsm.update(Gdx.graphics.getDeltaTime());
        gsm.render(sb);
    }

    @Override
    public void dispose () {
    }

    @Override
    public void resize(int width, int height) {
        gsm.resize(width, height);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }
}


public abstract class State {
    protected OrthographicCamera cam;
    protected GameStateManager gsm;
    protected Viewport viewport;

    protected State(GameStateManager gsm){
        this.gsm = gsm;
        cam = new OrthographicCamera();
        viewport = new FitViewport(Arlesian.V_WIDTH/2, Arlesian.V_HEIGHT/2, cam);
        viewport.apply();
    
    
    }

    protected abstract void handleInput();
    public abstract void update(float dt);
    public abstract void render(SpriteBatch sb);
    public abstract void resize(int width, int height);
    public abstract void dispose();
}



public class GameStateManager {
    private Stack<State> states;
    
    public GameStateManager(){
        states = new Stack<State>();
    }
    
    public void push(State state){
        states.push(state);
    }
    
    public void pop(){
        states.pop();
    }
    
    public void set(State state){
        states.peek().dispose();
        states.pop();
        states.push(state);
    }

    
    public void update(float dt){
        states.peek().handleInput();
        states.peek().update(dt);
    }
    
    public void render(SpriteBatch sb){
        states.peek().render(sb);
    }
    
    public void resize(int width, int height){
        states.peek().resize(width, height);
    }
}


public class FooState extends State {
    public FooState(GameStateManager gsm) {
        super(gsm);
        cam.setToOrtho(false, MyGame.V_WIDTH/2, MyGame.V_HEIGHT/2);
    }

    @Override
    protected void handleInput() {
        if(Gdx.input.isTouched()){
            gsm.set(new FooState2(gsm));
        }
    }

    @Override
    public void update(float dt) {
        cam.update();
    }

    @Override
    public void render(SpriteBatch sb) {
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void dispose() {

    }
}


public class FooState2 extends State {

    private Texture foo;
    private StretchViewport viewport;

    public FooState2(GameStateManager gsm) {
        super(gsm);
        foo = new Texture("badlogic.jpg");
        cam.setToOrtho(false, MyGame.V_WIDTH/2, MyGame.V_HEIGHT/2);
    }

    @Override
    protected void handleInput() {

    }

    @Override
    public void update(float dt) {
        cam.update();
    }

    @Override
    public void render(SpriteBatch sb) {
        sb.setProjectionMatrix(cam.combined);
        sb.begin();
        sb.draw(foo, 0, 0);
        sb.end();
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void dispose() {
        foo.dispose();
    }
}

So basically: FooState doesn't do anything except for pushing a FooState2 into the GameStateManager as soon as I touch the screen.

What happens: I touch the screen and I go into the FooState2 loop of handleInput, update, render (I'm positively sure of that thanks to some Syso's). But the badlogic logo doesn't render, instead I get a glClearColor screen. Then I click at the border of the application window and resize just a bit, and the badlogic logo renders again.

Another test: If I just begin by solely pushing a FooState2 into the GameStateManager, badlogic logo renders without me needing to resize the window.

Can you help me, please?
Thanks in advance!
Sorry for my English if mistakes were made.

Upvotes: 1

Views: 187

Answers (0)

Related Questions