【问题标题】:Libgdx sliding pause menuLibgdx 滑动暂停菜单
【发布时间】:2016-05-03 12:12:07
【问题描述】:

所以在我的游戏画面中,用户可以点击菜单按钮,然后该菜单按钮将暂停游戏并显示菜单。

我试图将菜单作为一个新阶段,但这只是打开一个新屏幕,按照我想要的方式设置菜单的图形,并使屏幕的其余部分保持黑色。

这是图片,您可以看到我在说什么:

我希望这个绿色部分顺利滑入游戏场景,我不想摆脱屏幕的这个黑色部分,而是让那个部分保持透明(我希望它只显示图像的绿色部分)。

试图找到一些关于暂停菜单的好教程,但没有成功。

这是我的暂停屏幕的代码:

public class Menu implements Screen{

    Stage menuStage = null;
    private Image menu_bg = null;

    private Main game = null;

    public Menu(Main gm){
        game = gm;
    }



    @Override
    public void show() {
        menuStage = new Stage(new StretchViewport(1920, 1080));
        Gdx.input.setInputProcessor(menuStage);
        menu_bg = new Image(new Texture(Gdx.files.internal("menuProba.png")));
        menuStage.addActor(menu_bg);

        menuButtons();
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        menuStage.draw();
        menuStage.act();
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }


    private void menuButtons(){
        Table menuButtons = new Table();
        menuButtons.setFillParent(true);

        final Image resumeGame = new Image(new Texture(Gdx.files.internal("playbutton.png")));
        final Image retryGame = new Image(new Texture(Gdx.files.internal("retrybutton.png")));
        final Image homeButton = new Image(new Texture(Gdx.files.internal("homebutton.png")));
        final Image exitButton = new Image(new Texture(Gdx.files.internal("exitbutton.png")));

        resumeGame.addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
                resumeGame.addAction(Actions.scaleTo(1, 1.1f,.1f));
                return true;
            }

            public void touchUp (InputEvent event, float x, float y, int pointer, int button){
                resumeGame.addAction(Actions.scaleTo(1, 1,.1f));
            }
        });


        retryGame.addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
                retryGame.addAction(Actions.scaleTo(1, 1.1f,.1f));
                return true;
            }

            public void touchUp (InputEvent event, float x, float y, int pointer, int button){
                retryGame.addAction(Actions.scaleTo(1, 1,.1f));
            }
        });


        homeButton.addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
                homeButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
                return true;
            }

            public void touchUp (InputEvent event, float x, float y, int pointer, int button){
                homeButton.addAction(Actions.scaleTo(1, 1,.1f));
                game.setScreen(new MainMenu(game));
            }
        });


        exitButton.addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
                exitButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
                return true;
            }

            public void touchUp (InputEvent event, float x, float y, int pointer, int button){
                exitButton.addAction(Actions.scaleTo(1, 1,.1f));
            }
        });


        /*HorizontalGroup horizontalGroup = new HorizontalGroup();
        horizontalGroup.addActor(resumeGame);
        horizontalGroup.addActor(retryGame);
        horizontalGroup.addActor(homeButton);
        horizontalGroup.addActor(exitButton);
        menuButtons.add(horizontalGroup);*/
        menuButtons.add(resumeGame).expand().left().padLeft(40);
        menuButtons.row();
        menuButtons.add(retryGame).expand().left().padLeft(40);
        menuButtons.row();
        menuButtons.add(homeButton).expand().left().padLeft(40);
        menuButtons.row();
        menuButtons.add(exitButton).expand().left().padLeft(40);
        menuStage.addActor(menuButtons);
    }


}

还有游戏画面:

public class GameScreen implements Screen, InputProcessor {

    boolean menuScreen;
    private Texture menuImage = null;

    public boolean buttonMenuTouched = false;
    public InputMultiplexer multiplexer = null;
    BitmapFont font;


    //SCORE-------------------------------------
    private SpriteBatch batch = null;
    private OrthographicCamera mCamera = null;
    private BitmapFont scoreFont = null;
    private int score = 0;
    //--------------------------------------------

    Main game = null;
    public Texture font_texture;

    public GameScreen(Main gm){
        game = gm;
    }

    Stage gameStage = null;
    private Image game_bg = null, menu_bg = null;

    private GameManager manager = null;

    @Override
    public void show() {

        mCamera = new OrthographicCamera(1920, 1080);
        font_texture = new Texture(Gdx.files.internal("font.png"));
        font_texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
        scoreFont = new BitmapFont(Gdx.files.internal("font.fnt"), new TextureRegion(font_texture), false);
        batch = new SpriteBatch();

        multiplexer = new InputMultiplexer();



        gameStage = new Stage(new StretchViewport(1920, 1080));
        multiplexer.addProcessor(this);
        multiplexer.addProcessor(gameStage);
        Gdx.input.setInputProcessor(multiplexer);

        game_bg = new Image(new Texture(Gdx.files.internal("pozadinaGameScreen.png")));
        gameStage.addActor(game_bg);

        menuImage = new Texture("menuProba.png");

        manager = new GameManager(game, this, gameStage);
        manager.createPlayer();
        manager.createBlueMonster();
        manager.createHUDButtons();
        manager.createGameOverStage();

        gameScreenButtoni();

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        gameStage.draw();
        gameStage.act();

        manager.checkButtons();
        manager.checkCollisions();

        batch.setProjectionMatrix(mCamera.combined);
        batch.begin();
        this.scoreFont.draw(batch, ""+manager.score, Gdx.graphics.getWidth() - 1070, Gdx.graphics.getHeight() - 580);



        batch.end();


        if (manager.gameOver == true){
            manager.gameOverStage.draw();
            manager.gameOverStage.act();

            Gdx.input.setInputProcessor(manager.gameOverStage);
        }
    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        manager.gameOverStage.dispose();
        gameStage.dispose();
        manager.dispose();
        game.setScreen(game.mainMenu);
    }



    // METODE INPUT PROCESORA

    @Override
    public boolean keyDown(int keycode) {
        return false;
    }

    @Override
    public boolean keyUp(int keycode) {
        return false;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        manager.shootBullet();
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }


    public void gameScreenButtoni(){

        //menuImage = new Image(new Texture(Gdx.files.internal("menuProba.png")));
        Table buttoni = new Table();
        buttoni.setFillParent(true);

        final Image menuButton = new Image(new Texture(Gdx.files.internal("menubutton.png")));
        menuButton.addListener(new InputListener(){
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
                menuButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
                buttonMenuTouched = true;
                return true;
            }

            public void touchUp (InputEvent event, float x, float y, int pointer, int button){
                menuButton.addAction(Actions.scaleTo(1, 1,.1f));
                buttonMenuTouched = false;
                game.setScreen(new Menu(game));



            }
        });

        final Image scoreText = new Image(new Texture(Gdx.files.internal("score.png")));


        buttoni.add(menuButton).expand().top().left().padLeft(20).padTop(20);
        buttoni.add(scoreText).expand().top().right().padTop(30).padRight(140);
        gameStage.addActor(buttoni);
    }

    public void menuScreen(){
        Stage menu = new Stage(new StretchViewport(400,400));
        menu_bg = new Image(new Texture(Gdx.files.internal("logoMali.png")));
        menu.addActor(menu_bg);
    }
}

我知道我做错了,但我该怎么做呢?按下按钮时画一个矩形还是什么?

【问题讨论】:

  • 在这种情况下,您的菜单不应与游戏分开。将其功能放入 GameScreen。绘制完gameStage后绘制菜单阶段。使用“操作”将您的内容移入和移出屏幕。顺便说一句,stage.act 应该在stage.draw 之前调用。否则,您的舞台将始终滞后一帧。
  • 感谢您的回复!我在一个屏幕中避免了 2 个阶段,因为我在某处读到它可能会影响性能,但我会尝试一下
  • 如果他们共享同一个 Sprite 批次,则不然。实例化单个 Sprite 批处理,然后将其传递给每个 Sprite 的构造函数。

标签: java android libgdx


【解决方案1】:

在我的游戏中,我在 libgdx 中创建了NavigationDrawer,如您所见:


可以使用示例代码完成此操作,只需执行几个步骤:

1-NavigationDrawer 类复制到您的项目中:

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;

/**
 * Created by Crowni on 10/6/2015.
 */
public class NavigationDrawer {
    // this value is suitable
    private static final float INTERVAL_SEC = 0.001f;

    // Some attributes for {@link NavigationDrawer}
    private static float CAM_MAIN_POSITION;
    public static float WIDTH;
    public static float SPEED;

    private static OrthographicCamera camera;

    /**
     * To ensure the {@link NavigationDrawerListener#onFinish()} called one time
     **/
    private static boolean isFinish = true;

    private static Task task;
    private static Timer timer = new Timer();

    private static NavigationDrawerListener listener;

    public interface NavigationDrawerListener {
        public void onStart();

        // May be you want to make some Actions here during sliding
        public void onRun();

        public void onFinish(float camX);
    }

    public static void initialize(Stage stage, NavigationDrawerListener listener) {
        NavigationDrawer.listener = listener;
        camera = ((OrthographicCamera) stage.getCamera());
        setNavigationDrawerDefault(stage);
        initializeTimerTask(false);
    }

    private static void setNavigationDrawerDefault(Stage stage) {
        WIDTH = stage.getWidth() - stage.getWidth() / 3;
        CAM_MAIN_POSITION = stage.getWidth() / 2;
        SPEED = 2f;
    }

    private static Task initializeTimerTask(boolean show) {
        task = new Task() {
            public void run() {
                if (!timer.isEmpty()) {
                    if (show)
                        camera.position.x -= SPEED;
                    else
                        camera.position.x += SPEED;

                    listener.onRun();
                } else if (isFinish) {
                    listener.onFinish(setDefaultCameraEndPostion(show));
                }
            }
        };
        return task;
    }

    /**
     * @param show
     *            : I passed it here because I know it is correct choice
     **/
    private static float setDefaultCameraEndPostion(boolean show) {
        isFinish = false;
        if (show)
            return camera.position.x = CAM_MAIN_POSITION - WIDTH;
        else
            return camera.position.x = CAM_MAIN_POSITION;
    }

    private static boolean isOpened() {
        return camera.position.x != CAM_MAIN_POSITION;
    }

    public static void show(boolean show) {
        if ((isOpened() && !show) || (!isOpened() && show))
            startTask(show);
    }

    private static void startTask(boolean show) {
        if (timer.isEmpty()) {
            isFinish = true;
            listener.onStart();
            timer.scheduleTask(initializeTimerTask(show), 0f, INTERVAL_SEC,
                    ((int) (WIDTH / SPEED)));
        }
    }
}

2- 在您的Screen 中写下以下内容:

@Override
public void show() {
    stage = new Stage(new StretchViewport(1080, 1920));

    // May be you want to make some Actions with NavigationDrawer state
    NavigationDrawerListener listener = new NavigationDrawerListener() {

        @Override
        public void onStart() {
            System.out.println("onStart");
        }

        @Override
        public void onRun() {
            System.out.println("onRun");
        }

        @Override
        public void onFinish(float camX) {
            System.out.println("onFinish: " + camX);
        }
    };

    // You must be initialize NavigationDrawer Firstly
    NavigationDrawer.initialize(stage, listener);

    // This image is sample to show how navigationDrawer look like on the screen
    Image background= new Image(new Texture(Gdx.files.internal("background.jpg")));
    background.addListener(new ClickListener() {
        private int clicked = 0;
        public void clicked(InputEvent event, float x, float y) {
            if (clicked % 2 == 0) {
                clicked++;
                NavigationDrawer.show(true);
            } else {
                clicked++;
                NavigationDrawer.show(false);
            }
        }
    });
    background.setFillParent(true);
    stage.addActor(background);

    Gdx.input.setInputProcessor(stage);

}

3-示例代码的结果如下:

4- 最后您可以在导航宽度中创建图像、标签、...演员,使其位置进入屏幕外,即负位置。尽情享受吧!


更新

这个Navigation Drawer更多性能和美滑。

【讨论】:

  • @Crowni 我有一个问题,timer.scheduleTask(initializeTimerTask.. 有时没有被触发。就像代码在 startTask() 方法中的 listener.onStart(); 处停止。它主要发生当我退出()我的游戏并在几秒钟后打开它时。可能是什么问题?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多