【问题标题】:How to refresh a transparent screen in libGdx如何在 libGdx 中刷新透明屏幕
【发布时间】:2022-11-07 09:50:14
【问题描述】:

我目前正在研究一个小型 libGdx 项目,我现在面临一些关于透明屏幕的麻烦。这个透明屏幕被称为“GameMenuScreen”,因为它可以在整个游戏过程中被调用。如果它被称为“GameMenuScreen”,则在 GameScreen 上方呈现,该 GameScreen 在背景中仍然可见。现在当我按下例如“保存”按钮,所有按钮都重复。我认为它的发生是因为屏幕不是每帧都刷新。但现在我不知道如何刷新屏幕并保持其透明度。 这是“GameMenuScreen”的代码:

public class GameMenuScreen extends ScreenAdapter {

    private TextureAtlas uiskinAtlas;
    private Skin skin;
    private OrthographicCamera camera;
    private Viewport viewport;
    private Stage stage;
    private Table table;
    private Vector3 position;
    private SpriteBatch batch;

    private TextButton continueGame;
    private TextButton loadGame;
    private TextButton settings;
    private TextButton mainMenu;
    private TextButton quit;
    private TextButton save;

    public GameMenuScreen() {
        
        uiskinAtlas = GameWindow.manager.get(Paths.uiskinAtlas, TextureAtlas.class);
        skin = new Skin(Gdx.files.internal(Paths.uiskinJson), uiskinAtlas);
        camera = new OrthographicCamera();
        position = new Vector3(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 0);
        camera.position.set(position);
        viewport = new ScreenViewport(camera);
        stage = new Stage(viewport);
        batch = new SpriteBatch();

        table = new Table();
        
        continueGame = new TextButton("Continue Game", skin);
        loadGame = new TextButton("Load Game", skin);
        settings = new TextButton("Settings", skin);
        mainMenu = new TextButton("Main Menu", skin);
        quit = new TextButton("Quit", skin);
        save = new TextButton("Save", skin);
        
        
        continueGame.setColor(Color.ROYAL);
        loadGame.setColor(Color.ROYAL);
        settings.setColor(Color.ROYAL);
        mainMenu.setColor(Color.ROYAL);
        quit.setColor(Color.ROYAL);
        save.setColor(Color.ROYAL);
        
        createUI();
    }

    @Override
    public void show() {
        Gdx.input.setInputProcessor(stage);
    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 0f);
        
        batch.enableBlending();
        batch.begin();
        continueGame.draw(batch, 0);
        loadGame.draw(batch, 0);
        settings.draw(batch, 0);
        mainMenu.draw(batch, 0);
        quit.draw(batch, 0);
        save.draw(batch, 0);
        batch.end();
        
        stage.act();
        stage.draw();
    }

    private void createUI() {
        
        table.setFillParent(true);
        table.center();

        setButtonInput();

        table.add(continueGame).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(loadGame).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(save).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(settings).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(mainMenu).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(quit).width(250);
        table.row().space(5, 5, 0, 0);

        stage.addActor(table);
        
    }

    private void setButtonInput() {

        continueGame.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                GameWindow.INSTANCE.setScreen(Screens.getGameScreen());
            }
        });

        loadGame.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Savegame.load();
                Screens.getGameScreen().setWorldCreated(false);
                GameWindow.INSTANCE.setScreen(Screens.getGameScreen());
            }
        });

        save.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Savegame.save();
            }
        });

        mainMenu.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                GameWindow.INSTANCE.setScreen(Screens.getMainMenuScreen());
            }
        });

        quit.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Gdx.app.exit();
            }
        });
    }
    
    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
        position = new Vector3(viewport.getScreenWidth() / 2, viewport.getScreenHeight() / 2, 0);
        camera.position.set(position);
    }

每帧刷新屏幕的正常方法是调用这两个代码段:

Gdx.gl.glClearColor(0.35f, 0, 0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

但如前所述:屏幕在调用时会失去透明度。

为了更好地理解一张显示倍增的图片:

我希望你能帮助我。

【问题讨论】:

  • 欢迎来到 SO!请写清楚的问题陈述。你可能想看看"Why is "Can someone help me?" not an actual question?"
  • 你会为这篇文章推荐什么明确的问题陈述?
  • 有很多方法可以在这里表达一个特定的问题,我没有信心在你的情况下向你推荐一个。也许类似于“为什么我的代码的行为方式与其预期的方式不同,如何解决?“(这将反映你想要什么,但可能会给你一个”你试过调试吗?” 回应,我认为这是一个公平的回应)。请注意,definition effort 在提问时是您自己的责任的一部分。

标签: java libgdx screen transparency game-development


【解决方案1】:

render() 方法中删除Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 意味着您永远不会清除屏幕的像素缓冲区,这意味着您绘制的所有内容都将绘制在先前渲染帧的像素上。

如果您需要保存前一个屏幕的图片并将其用作菜单的背景,您应该对其进行某种“屏幕截图”并将其保存到纹理中。 LibGDX 中已经存在一个非常方便的方法 - ScreenUtils.getFrameBufferTexture()LibGDX ScreenUtils source code。只需在切换到菜单之前调用此方法并将其用作背景图像的常规纹理(但请记住 dispose() 旧纹理,否则它们会污染您的记忆)。

您也可以在渲染 UI 之前在 render() 方法中调用此方法,它会拾取没有 UI 元素的游戏图片,这可能更适合菜单背景。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多