libgdx : Spritebatch not rendering until resize

178 Views Asked by At

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.

0

There are 0 best solutions below