Java - Libgdx : Keep actor's position even screen's resolution changes

♀尐吖头ヾ 提交于 2019-12-25 08:09:13

问题


issue is next one: my game is built for 1080x1920 pixels screen but if I run it in other resolutions my actors' position is switching.

Some pictures if you haven't understood:

~> original resolution

~> other resolution

I looked for an answer for days in Google, Stackoverflow, forums, couldn't find the right answer for my problem, here's my code:

public class PlayScreen implements Screen {

    private Main game;

    private Stage stage;

    Music music;
    Sound sound;




    private class MenuGame extends Actor {
        Texture menu = new Texture(Gdx.files.internal("sprite/menu.png"));

        @Override
        public void draw(Batch batch, float alpha) {
            batch.draw(menu, 0, 0,Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        }
    }

    private class NewGame extends Actor {
        Texture newgame = new Texture(Gdx.files.internal("sprite/new.png"));

        @Override
        public void draw(Batch batch, float alpha) {
            batch.draw(newgame, 350, 1000);
        }
    }

    private class LoadGame extends Actor {
        Texture loadgame = new Texture(Gdx.files.internal("sprite/load.png"));

        @Override
        public void draw(Batch batch, float alpha) {
            batch.draw(loadgame, 350, 830);
        }
    }

    private class CreditsGame extends Actor {
        Texture creditsgame = new Texture(Gdx.files.internal("sprite/credits.png"));

        @Override
        public void draw(Batch batch, float alpha) {
            batch.draw(creditsgame, 350, 660);
        }
    }

    private class DonsGame extends Actor {
        Texture donsgame = new Texture(Gdx.files.internal("sprite/dons.png"));

        @Override
        public void draw(Batch batch, float alpha) {
            batch.draw(donsgame, 350, 490);
        }
    }


    // our create()

    public PlayScreen(final Main game) {
        this.game = game;


        Gdx.input.setInputProcessor(stage);

        final Sound sound = Gdx.audio.newSound(Gdx.files.internal("sound/buttonsound.mp3"));

        music = Gdx.audio.newMusic(Gdx.files.internal("sound/brun.mp3"));
        music.setLooping(true);
        music.setVolume(0.2f);
        music.play();




        // actors

        MenuGame menu = new MenuGame();     // BACKGROUND
        stage.addActor(menu);

        final NewGame newGame = new NewGame();   // BOUTON NEW
        stage.addActor(newGame);
        newGame.setX(350);
        newGame.setY(1000);
        newGame.setWidth(410);
        newGame.setHeight(100);


        LoadGame loadGame = new LoadGame();   // BOUTON LOAD
        stage.addActor(loadGame);
        loadGame.setX(350);
        loadGame.setY(830);
        loadGame.setWidth(410);
        loadGame.setHeight(100);

        CreditsGame creditsGame = new CreditsGame();   // BOUTON CREDITS
        stage.addActor(creditsGame);
        creditsGame.setX(350);
        creditsGame.setY(660);
        creditsGame.setWidth(410);
        creditsGame.setHeight(100);

        DonsGame donsGame = new DonsGame();   // BOUTON DONS
        stage.addActor(donsGame);
        donsGame.setX(350);
        donsGame.setY(490);
        donsGame.setWidth(410);
        donsGame.setHeight(100);






        // actions

        newGame.addListener(new ClickListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)   // NEW BOUTON ACTION
            {
                sound.play(0.2f);
                music.stop();
                game.setScreen(new Story(game));
                return true;
            }
        });


        loadGame.addListener(new ClickListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)   // LOAD BOUTON ACTION
            {
                sound.play(0.2f); //faire un truc ici
                return true;
            }

        });




        creditsGame.addListener(new ClickListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)   // CREDITS BOUTON ACTION
            {
                sound.play(0.2f);//faire un truc ici
                return true;
            }
        });


        donsGame.addListener(new ClickListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)   // DONS BOUTON ACTION
            {
                sound.play(0.2f);//faire un truc ici
                return true;
            }
        });


    }



    @Override
    public void show() {
    }

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

    }

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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

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

}

回答1:


You are positioning everything after hardcoded values. So right now your game is very resolution depended.

What you need to use is Viewports. Here are some links to get you started:

Brent Aureli - Aspect Ratios & Viewports

libgdx github - viewports

libgdx github - scene2d




回答2:


this is happening because different devices has different screen size. so it will appear differently . to avoid this you must use the viewPort .for more clarification you must read the libgdx api about the multi resolution and the viewPort . here i will suggest you some sample code to avoid this multi screen issue. please follow this pattern which acan solve your problem.

// in your main class
public class myGame extends ApplicationAdapter {

    public OrthographicCamera camera
    public Viewport viewPort
    private SpriteBatch batch;
    private BitMapFont myScoreFont
    public myGame() {

    }

    @Override
    public void create() {
            myScoreFont = new BitmapFont(Gdx.files.internal(font.txt), true);
        batch = new SpriteBatch();
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera();
        camera.position.set(0, 0, 0);
        camera.update();
        camera.setToOrtho(false, Constants.APP_WIDTH, Constants.APP_HEIGHT);
        viewPort = new FillViewport(1280, 800, camera);


    }

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



    @Override
    public void render() {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
        float deltaTime = Gdx.graphics.getDeltaTime();
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        myScoreFont.draw(batch,"myText",0,0)
        batch.end();

    }

    @Override
    public void resize(int width, int height) {
        viewPort.update(width, height);
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

for more details you must read the below link about the viewport

https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/viewport/FillViewport.html



来源:https://stackoverflow.com/questions/39718125/java-libgdx-keep-actors-position-even-screens-resolution-changes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!