如何使这个libGDX阶段/按钮接收触摸?

时间:2014-03-23 20:35:48

标签: java android-layout libgdx

我能够渲染图像和按钮小部件,但是,我还没有成功地使buttonPlay接收输入。该假设是触摸时未呈现的按钮的向下图像的结果,并且onPlayClicked()也不执行。

我相信我正在将舞台设置为InputProcessor。

我已经详尽地搜索了S.O.的解决方案。无济于事。

有问题的Button是ScreenMenuMain.java的buildControlsLayer()中的buttonPlay。

编辑:屏幕流程:我想从ScreenMenuMain.java切换到另一个名为ScreenGame.java的屏幕。

我试图通过指向屏幕切换的DirectedGame.java来做到这一点。它还添加了一个过渡效果,使前一阶段的输入处理器无效,并将输入处理器设置为新屏幕的舞台。

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 [用于设置InputProcessor和切换屏幕]

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

2 个答案:

答案 0 :(得分:1)

您必须像这样

将InputListnener添加到您的按钮
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);
        }

    });

答案 1 :(得分:0)