繁体   English   中英

LibGDX:如何从主游戏屏幕重复显示/隐藏叠加弹出菜单

[英]LibGDX: How to show/hide an overlay popup menu from the main game screen repetitively

我正在做一个名为 Fuego Peligro 的游戏(基于另一个名为 Ninja Rabbit 的 LibGDX“教程”项目,nfantone, https://github.com/nfantone/ninja-rabbit )作为我在我大学的 BIT 课程中的论文,我想要在主游戏屏幕上显示/隐藏某种叠加菜单。

弹出菜单就像一个检查站,显示来自主要平台游戏的简单琐事类型的迷你游戏。 它通过 Telegraph (handleMessage) 方法调用。 唯一的问题是当消息重复时,如果之前已经显示过弹出窗口,它不想再次重新显示。

所有文件和其他详细信息都在此链接中: https : //github.com/NinjaSiren/FuegoPeligro

所有 .java 文件都在这里: https : //github.com/NinjaSiren/FuegoPeligro/tree/master/core/src/com/mygdx/fuegopeligro

这是调用所有游戏内叠加层进行渲染的 java 类:LevelGraphicsProcessor.java

public class LevelGraphicsProcessor implements GraphicsProcessor, Telegraph {
    private final LevelRenderer mapRenderer;
    private final GameOverOverlay gameOver;
    private final LevelEndOverlay levelEnd;
    private MultipleChoice multipleChoice;
    private FourPicsOneWord fourPicsOneWord;
    private LetterPuzzle letterPuzzle;
    private Wordscapes wordscapes;

    private boolean renderGameOver;
    private boolean renderLevelEnd;
    private boolean minicamSelection;
    private final CurrentPlayerStatus status;
    private final NinjaRabbit ninja;
    private final Entity entity;

    public LevelGraphicsProcessor(final AssetManager assets, final LevelRenderer mapRenderer,
                                  final FuegoPeligro game, final NinjaRabbit ninjaRabbit,
                                  final CurrentPlayerStatus player) {
        status = player;
        ninja = ninjaRabbit;
        if (ninjaRabbit == null) {
            throw new IllegalArgumentException("'character' cannot be null"); }
        this.entity = ninjaRabbit;

        gameOver = new GameOverOverlay(game.getBatch(), assets, game);
        levelEnd = new LevelEndOverlay(game.getBatch(), assets, game);
        multipleChoice = new MultipleChoice(assets, game, ninjaRabbit);
        fourPicsOneWord = new FourPicsOneWord(assets, game, ninjaRabbit);
        letterPuzzle = new LetterPuzzle(assets, game, ninjaRabbit);
        wordscapes = new Wordscapes(assets, game, ninjaRabbit);
        this.mapRenderer = mapRenderer;
        MessageManager.getInstance().addListeners(this, MessageType.GAME_OVER.code());
        MessageManager.getInstance().addListeners(this, MessageType.FINISH_LEVEL.code());
        MessageManager.getInstance().addListeners(this, MessageType.COLLECTED.code());
    }

    @Override
    public void update(final Entity character, final Camera camera) {
        mapRenderer.render((OrthographicCamera) camera);
    }

    /*
     * (non-Javadoc)
     *
     * @see com.mygdx.fuegopeligro.graphics.GraphicsProcessor#draw(com.mygdx.fuegopeligro.entity.Entity,
     * com.badlogic.gdx.graphics.g2d.Batch)
     */
    @Override
    public void draw(final Entity entity, final Batch batch) {
        mapRenderer.update();

        if (renderGameOver) {
            gameOver.render(Gdx.graphics.getDeltaTime());
        } else if (renderLevelEnd) {
            levelEnd.render(Gdx.graphics.getDeltaTime());
        } else if (minicamSelection) {
            multipleChoice.render(Gdx.graphics.getDeltaTime());
            wordscapes.render(Gdx.graphics.getDeltaTime());
            letterPuzzle.render(Gdx.graphics.getDeltaTime());
            fourPicsOneWord.render(Gdx.graphics.getDeltaTime());

            entity.changeState(NinjaRabbitState.IDLE);
            byte worldValue = status.getCurrentWorld();
            //short levelValue = status.getCurrentLevel();
            short mgValue = status.getMGValue();

            if (worldValue == 1) {
                //short easyValue = status.getEqaValue();
                if (mgValue == 1) {
                    multipleChoice.setVisible(true);
                    Gdx.input.setInputProcessor(multipleChoice.stage);
                    if (multipleChoice.enterAnswer.isPressed()) {
                        multipleChoice.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 2) {
                    wordscapes.setVisible(true);
                    Gdx.input.setInputProcessor(wordscapes.stage);
                    if (wordscapes.enterAnswer.isPressed()) {
                        wordscapes.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 3) {
                    letterPuzzle.setVisible(true);
                    Gdx.input.setInputProcessor(letterPuzzle.stage);
                    if (letterPuzzle.enterAnswer.isPressed()) {
                        letterPuzzle.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 4) {
                    fourPicsOneWord.setVisible(true);
                    Gdx.input.setInputProcessor(fourPicsOneWord.stage);
                    if (fourPicsOneWord.enterAnswer.isPressed()) {
                        fourPicsOneWord.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                }
            } else if (worldValue == 2) {
                //short hardValue = status.getHqaValue();
                if (mgValue == 1) {
                    multipleChoice.setVisible(true);
                    Gdx.input.setInputProcessor(multipleChoice.stage);
                    if (multipleChoice.enterAnswer.isPressed()) {
                        multipleChoice.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 2) {
                    wordscapes.setVisible(true);
                    Gdx.input.setInputProcessor(wordscapes.stage);
                    if (wordscapes.enterAnswer.isPressed()) {
                        wordscapes.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 3) {
                    letterPuzzle.setVisible(true);
                    Gdx.input.setInputProcessor(letterPuzzle.stage);
                    if (letterPuzzle.enterAnswer.isPressed()) {
                        letterPuzzle.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                } else if (mgValue == 4) {
                    fourPicsOneWord.setVisible(true);
                    Gdx.input.setInputProcessor(fourPicsOneWord.stage);
                    if (fourPicsOneWord.enterAnswer.isPressed()) {
                        fourPicsOneWord.setVisible(false);
                        Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
                    }
                }
            }
        }
    }

    @Override
    public boolean handleMessage(final Telegram msg) {
        renderGameOver = msg.message == MessageType.GAME_OVER.code();
        renderLevelEnd = msg.message == MessageType.FINISH_LEVEL.code();
        minicamSelection = msg.message == MessageType.COLLECTED.code();
        return true;
    }

    @Override
    public void resize(final int width, final int height) {
        gameOver.resize(width, height);
        levelEnd.resize(width, height);
        multipleChoice.resize(width, height);
        wordscapes.resize(width, height);
        letterPuzzle.resize(width, height);
        fourPicsOneWord.resize(width, height);
    }

    @Override
    public void dispose() {
        gameOver.dispose();
        levelEnd.dispose();
        multipleChoice.dispose();
        wordscapes.dispose();
        letterPuzzle.dispose();
        fourPicsOneWord.dispose();
    }
}

这是我想在收到消息时显示的弹出小游戏之一,并在单击按钮时隐藏。:MultipleChoice.java

public class MultipleChoice implements Disposable {
    private static final String QUESTION_LABEL = "CHECKPOINT: MULTIPLE CHOICE";
    private static final String ENTER_ANSWER = "ENTER";
    private static final String HINT_ANSWER = "HINT";

    public final Stage stage;
    private final NinjaRabbit ninja;
    private final Label QuestionLabel;
    private final Label QuestionText;
    private final TextButton answer1;
    private final TextButton answer2;
    private final TextButton answer3;
    private final TextButton answer4;
    public final TextButton enterAnswer;
    private final TextButton enterHints;
    private final Table table;

    public MultipleChoice(final AssetManager assets, final FuegoPeligro game,
                          final NinjaRabbit ninjaRabbit) {
        stage = new Stage(new ScreenViewport(), game.getBatch());
        ninja = ninjaRabbit;

        Label.LabelStyle style = new Label.LabelStyle();
        AssetManager assetManager = new AssetManager();
        assetManager.load(Assets.GAME_UI_SKIN);
        assetManager.finishLoading();
        Skin skin = assetManager.get(Assets.GAME_UI_SKIN);

        style.fontColor = Color.WHITE;
        style.font = assets.get(Assets.HUD_FONT);
        QuestionLabel = new Label(QUESTION_LABEL, style);

        style.fontColor = Color.WHITE;
        style.font = assets.get(Assets.HUD_FONT);
        QuestionText = new Label("", style);

        answer1 = new TextButton("", skin);
        answer1.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });
        answer2 = new TextButton("", skin);
        answer2.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });
        answer3 = new TextButton("", skin);
        answer3.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });
        answer4 = new TextButton("", skin);
        answer4.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });

        // enter answer
        enterAnswer = new TextButton(ENTER_ANSWER, skin);
        enterAnswer.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });

        // enter hints
        enterHints = new TextButton(HINT_ANSWER, skin);
        enterHints.addListener(new ClickListener() {
            @Override
            public void clicked(final InputEvent event, final float x, final float y) {

            }
        });

        table = new Table();
        table.setFillParent(true);
        table.setDebug(true);

        table.add(QuestionLabel).expand(true, false).center();
        table.row().pad(20, 0, 0, 10);
        table.add(QuestionText).expand(true, false);
        table.row().pad(10, 0, 0, 20);
        table.add(answer1).expand(true, false);
        table.add(answer2).expand(true, false);
        table.row().pad(10, 0, 0, 20);
        table.add(answer3).expand(true, false);
        table.add(answer4).expand(true, false);
        table.row().pad(10, 0, 0, 20);
        table.add(enterAnswer).expand(true, false);
        table.add(enterHints).expand(true, false);
        table.setVisible(false);

        stage.addActor(table);
        stage.setKeyboardFocus(table);
    }

    public void render(final float delta) {
        Gdx.gl20.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

        Gdx.gl20.glDisable(GL20.GL_BLEND);
        stage.getBatch().end();
        stage.act(delta);
        stage.draw();
        stage.getBatch().begin();
    }

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

    @Override
    public void dispose() {
        stage.dispose();
    }

    public void setVisible(boolean value) {
        table.setVisible(value);
    }
}

使用 LibGDX 时,UI 的标准约定是使用 Scene2D,并且 Scene2D 对象必须包含在Stage - 要使用像叠加层这样的窗口,可以使用特殊的Table派生类: Window类。

您希望在叠加层中的任何Actor都可以添加到Window实例并像其自己的StageTable一样定位在其中,并且可以将Window添加到场景中并从场景中删除 - 甚至可以使用淡入淡出fade(In/Out)动作(而不是像下面的例子那样直接添加和删除):

public class ExampleClass {

    ...
    private Stage stage = new Stage(...);
    private Window popUp = new Window("...");
    private TextButton windowButton1 = ..., windowButton2 = ...;
    ...

    public ExampleClass() {
        ...

        Gdx.setInputProcessor(stage); //Allows input to Scene2D components - important!
        //Register click listeners to buttons to close window when clicked
        windowButton1.addListener(new CloseButtonListener(this));
        windowButton2.addListener(new CloseButtonListener(this));
        ...
        //Add buttons to window
        popUp.add(windowButton1);
        popUp.add(windowButton2);
        ...
    }

    //Run when message is received
    public void messageReceived() {
        ...
        stage.add(popUp); //Add window to stage you want to overlay
        ...
    }

    ...

    public Stage getStage() {
        return stage;
    }

    public Window getPopUp() {
        return popUp;
    }

    ...
}

class CloseButtonListener implements ClickListener { //Inner class for handling button clicks, multiple can be created for different button types with different logic when window is closed.

    private ExampleClass exampleInstance;

    public CloseButtonListener(ExampleClass exampleInstance) {
        this.exampleInstance = exampleInstance;
    }

    //Remove the window from the stage when the button is clicked, handles any other logic too depending on button.
    @Override
    public void clicked(InputEvent event, float x, float y) {
        ...
        exampleInstance.addAction(Actions.removeActor());
        ...
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM