Search code examples
javaandroidlibgdx

Click Listeners do not work when maximizing window or resize (LibGDX)


I'm experimenting with libgdx libraries, making a menu that moves me to different screens. I create a small application using LwjglApplication. The Click event works fine when having the window with minimized size, but at the moment of maximizing, the event stops working.

Example:

Here, the ClickListener works enter image description here

And here... the ClickListener stops working...enter image description here

The Menu code:

package mrbulb;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

public class Menu implements Screen {
    private Stage menu, sobre;
    private ScreenBoss pantalla;
    private Game juego;

    public Menu(Game g){
      juego = g;     
      menu = new Stage();
      ActorBase fondo = new ActorBase();
      fondo.setTextura(new Texture(Gdx.files.internal("assets/fondo_temp.png")));
      fondo.setWidth(640);
      fondo.setHeight(500);
      menu.addActor(fondo);
      LabelStyle style = new LabelStyle(new BitmapFont(),Color.ORANGE);
      LabelStyle style2 = new LabelStyle(new BitmapFont(),Color.GREEN);
      LabelStyle style3 = new LabelStyle(new BitmapFont(),Color.RED);
      Label empezar = new Label("Empezar juego",style);
      empezar.setFontScale(2);
      empezar.setPosition(230, 250);
      empezar.addAction(
        Actions.forever(Actions.sequence(Actions.color( new Color(1, 1, 0, 1), 0.5f ),Actions.delay( 0.5f ),Actions.color( new Color(0.5f, 0.5f, 0, 1), 0.5f )))
      );
      Label instrucciones = new Label("Como jugar",style);
      instrucciones.setFontScale(2);
      instrucciones.setPosition(250, 190);
      instrucciones.addAction(
        Actions.forever(Actions.sequence(Actions.color( new Color(1, 1, 0, 1), 0.5f ),Actions.delay( 0.5f ),Actions.color( new Color(0.5f, 0.5f, 0, 1), 0.5f )))
      );
      Label acerca = new Label("Acerca de",style);
      acerca.setFontScale(2);
      acerca.setPosition(260,130);
      acerca.addAction(
        Actions.forever(Actions.sequence(Actions.color( new Color(1, 1, 0, 1), 0.5f ),Actions.delay( 0.5f ),Actions.color( new Color(0.5f, 0.5f, 0, 1), 0.5f )))
      );
      acerca.addListener(new ClickListener(){
        @Override
        public void clicked(InputEvent event, float x, float y){
            juego.setScreen(new ScreenBoss(sobre));
            Gdx.input.setInputProcessor(sobre);
        };  
      });
      Label salir = new Label("Salir",style);
      salir.setFontScale(2);
      salir.setPosition(294, 70);
      salir.addAction(
        Actions.forever(Actions.sequence(Actions.color( new Color(1, 1, 0, 1), 0.5f ),Actions.delay( 0.5f ),Actions.color( new Color(0.5f, 0.5f, 0, 1), 0.5f )))
      );
      menu.addActor(empezar);
      menu.addActor(instrucciones);
      menu.addActor(acerca);
      menu.addActor(salir);
      sobre = new Stage();
      ActorBase fondAc = new ActorBase();
      fondAc.setTextura(new Texture(Gdx.files.internal("assets/Foco.png")));
      fondAc.setWidth(640);
      fondAc.setHeight(500);
      sobre.addActor(fondAc);
      Label leyenda = new Label("Este juego fue desarrollado por Daniel Phillips,\ncon meros fines educativos (o \"Autodidactas\")."
              + "\nSe hizo con la intencion de explorar el vasto \nmundo del desarrollo de videojuegos, ademas\n"
              + "de explorar las librerias LibGDX.\n\nEl juego esta desarrollado en el lenguaje JAVA.",style2);
      leyenda.setFontScale(2);
      leyenda.setPosition(10, 230);
      Label regresa = new Label("Regresar a la pantalla anterior",style3);
      regresa.setFontScale(2);
      regresa.setPosition(130, 50);
      regresa.addAction(
        Actions.forever(Actions.sequence(Actions.color( new Color(1, 1, 0, 1), 0.5f ),Actions.delay( 0.5f ),Actions.color( new Color(0.5f, 0.5f, 0, 1), 0.5f )))
      );
      regresa.addListener(new ClickListener(){
          @Override
          public void clicked(InputEvent event, float x, float y){
              juego.setScreen(new ScreenBoss(menu));
              Gdx.input.setInputProcessor(menu);
          }
      });
      sobre.addActor(leyenda);
      sobre.addActor(regresa);
      Gdx.input.setInputProcessor(menu);
    }

    @Override
    public void show() {}

    @Override
    public void render(float dt) {
        menu.act(dt);
        Gdx.gl.glClearColor(0.8f, 0.8f, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        menu.draw();
    }

    @Override
    public void resize(int i, int i1) {}
    @Override
    public void pause() {}
    @Override
    public void resume() {}
    @Override
    public void hide() {}
    @Override
    public void dispose() {}  
}

Solution

  • You need to update stage viewport.

    @Override
    public void resize(int width, int height) {
        stage.getViewport().update(width,height);
    }
    

    Touch/clicked detected when touchpoint is inside Actor bounds, when you use setFontScale(scale); on Label, It changes his font size only not Actor bounds so you should set size of that Label. You can use container as parent of that Label and scale container according to your requirement instead of scaling font.

    You can use stage.setDebugAll(true); for debugging and see all your Actor bounds.

    By default constructor of stage use StretchViewport with screen width and height as viewport worldwidth and worldheight. StretchViewport scales the source to fill the target and that may cause the source to not keep the same aspect ratio so it's better to you other viewport with predefined worldwidth and worldheight of viewport. I'll recommend to use ExtendViewport because it fullfill our requirement in most of the cases.