簡體   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