Reputation: 11
I'm able to get the Image and Button widgets to render, however, I have not yet succeeded in getting the buttonPlay to receive input. This hypothesis is a result of the down image of the button not rendering when touched, and the onPlayClicked() not executing as well.
I believe that I am properly setting the Stage as the InputProcessor.
I have exhaustively searched for solutions on S.O. to no avail.
The problematic Button is the buttonPlay within the buildControlsLayer() of ScreenMenuMain.java.
Edit: Screen flow process: I want to switch from ScreenMenuMain.java to another screen named ScreenGame.java.
I am trying to do this via DirectedGame.java which directs the screen switches. It also adds a transition effect, nullifies the input processor from the previous stage, and sets the input processor to the stage from the new screen.
ScreenMenuMain.java
public class ScreenMenuMain extends AbstractGameScreen {
private Stage stage;
private Skin skinMenuMain;
//menu
private Image menuLogo;
private Button buttonPlay;
public ScreenMenuMain (DirectedGame game) {
super(game);
}
@Override
public void render (float deltaTime) {
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(deltaTime);
stage.draw();
}
@Override
public void resize (int width, int height) {
stage.setViewport(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT, false);
}
@Override
public void show () {
stage = new Stage();
rebuildStage();
}
@Override
public void hide () {
stage.dispose();
skinMenuMain.dispose();
}
private void rebuildStage () {
skinMenuMain = new Skin(Gdx.files.internal(Constants.SKIN_MAINMENU), new TextureAtlas(Constants.TEXTURE_ATLAS_MAINMENU));
// build all layers
Table layerLogo = buildLogoLayer();
Table layerControls = buildControlsLayer();
// assemble stage for menu screen
stage.clear();
Stack stack = new Stack();
stage.addActor(stack);
stack.setSize(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT);
stack.add(layerLogo);
stack.add(layerControls);
}
private Table buildLogoLayer () {
Table layer = new Table();
layer.top();
// + Logo
menuLogo = new Image(skinMenuMain, "menulogo");
layer.add(menuLogo);
layer.row().expandY();
return layer;
}
private Table buildControlsLayer () {
Table layer = new Table();
layer.left().bottom();
//add play button
buttonPlay = new Button(skinMenuMain, "play");
layer.add(buttonPlay);
buttonPlay.addListener(new ChangeListener() {
@Override
public void changed (ChangeEvent event, Actor actor) {
System.out.println("touch down");
onPlayClicked();
}
});
return layer;
}
private void onPlayClicked () {
ScreenTransition transition = ScreenTransitionFade.init(0.75f);
game.setScreen(new ScreenGame(game), transition);
}
@Override
public InputProcessor getInputProcessor () {
return stage;
}
}
DirectedGame.java [For setting InputProcessor and switching screens]
public abstract class DirectedGame implements ApplicationListener {
private boolean init;
private AbstractGameScreen currScreen;
private AbstractGameScreen nextScreen;
private FrameBuffer currFbo;
private FrameBuffer nextFbo;
private SpriteBatch batch;
private float t;
private ScreenTransition screenTransition;
public void setScreen (AbstractGameScreen screen) {
setScreen(screen, null);
}
public void setScreen (AbstractGameScreen screen, ScreenTransition screenTransition) {
int w = Gdx.graphics.getWidth();
int h = Gdx.graphics.getHeight();
if (!init) {
currFbo = new FrameBuffer(Format.RGB888, w, h, false);
nextFbo = new FrameBuffer(Format.RGB888, w, h, false);
batch = new SpriteBatch();
init = true;
}
// start new transition
nextScreen = screen;
nextScreen.show(); // activate next screen
nextScreen.resize(w, h);
nextScreen.render(0); // let next screen update() once
if (currScreen != null) currScreen.pause();
nextScreen.pause();
Gdx.input.setInputProcessor(null); // disable input
this.screenTransition = screenTransition;
t = 0;
}
@Override
public void render () {
// get delta time and ensure an upper limit of one 60th second
float deltaTime = Math.min(Gdx.graphics.getDeltaTime(), 1.0f / 60.0f);
if (nextScreen == null) {
// no ongoing transition
if (currScreen != null) currScreen.render(deltaTime);
} else {
// ongoing transition
float duration = 0;
if (screenTransition != null) duration = screenTransition.getDuration();
t = Math.min(t + deltaTime, duration);
if (screenTransition == null || t >= duration) {
// no transition effect set or transition has just finished
if (currScreen != null) currScreen.hide();
nextScreen.resume();
// enable input for next screen
Gdx.input.setInputProcessor(nextScreen.getInputProcessor());
// switch screens
currScreen = nextScreen;
nextScreen = null;
screenTransition = null;
} else {
// render screens to FBOs
currFbo.begin();
if (currScreen != null) currScreen.render(deltaTime);
currFbo.end();
nextFbo.begin();
nextScreen.render(deltaTime);
nextFbo.end();
// render transition effect to screen
float alpha = t / duration;
screenTransition.render(batch, currFbo.getColorBufferTexture(), nextFbo.getColorBufferTexture(), alpha);
}
}
}
@Override
public void resize (int width, int height) {
if (currScreen != null) currScreen.resize(width, height);
if (nextScreen != null) nextScreen.resize(width, height);
}
@Override
public void pause () {
if (currScreen != null) currScreen.pause();
}
@Override
public void resume () {
if (currScreen != null) currScreen.resume();
}
@Override
public void dispose () {
if (currScreen != null) currScreen.hide();
if (nextScreen != null) nextScreen.hide();
if (init) {
currFbo.dispose();
currScreen = null;
nextFbo.dispose();
nextScreen = null;
batch.dispose();
init = false;
}
}
}
Upvotes: 1
Views: 585
Reputation: 737
Also check out ClickListeners: http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ClickListener.html
Upvotes: 0
Reputation: 31
You must add InputListnener to your button like this
buttonPlay.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("touch down");
onPlayClicked();
return super.touchDown(event, x, y, pointer, button);
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
// Do some stuff on touchUp
super.touchUp(event, x, y, pointer, button);
}
});
Upvotes: 1