Java - Libgdx : Keep actor's position even scr

2019-09-10 18:53发布

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();
    }

}

2条回答
SAY GOODBYE
2楼-- · 2019-09-10 19:26

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

查看更多
叼着烟拽天下
3楼-- · 2019-09-10 19:30

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

查看更多
登录 后发表回答