问题描述:

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;

}

}

}

网友答案:

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);
        }

    });
网友答案:

Also check out ClickListeners: http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ClickListener.html

相关阅读:
Top