81 votes

Comment traiter les différents formats d'aspect dans libGDX?

J'ai mis en place quelques écrans à l'aide de libGDX qui serait évidemment d'utiliser l' Screen classe fournie par le libGDX cadre. Cependant, la mise en œuvre de ces écrans ne fonctionne qu'avec les pré-défini les tailles d'écran. Par exemple, si le sprite qui a été conçu pour une résolution de 640 x 480 taille de l'écran (4:3 rapport d'Aspect), il ne fonctionnera pas comme prévu sur d'autres tailles d'écran, car les sprites passer par l'écran de limites et ne sont pas redimensionnées à la taille de l'écran. En outre, si une simple mise à l'échelle qui aurait été fourni par le libGDX, la question, je suis confronté aurait toujours été là parce que ce serait provoquer le ratio d'aspect de l'écran de jeu pour changer.

Après des recherches sur internet, je suis tombé sur un blog/forum qui avait débattu de cette question. J'ai mis en œuvre et jusqu'à présent, il fonctionne très bien. Mais je tiens à confirmer si c'est la meilleure option pour atteindre ce ou s'il existe de meilleures alternatives. Ci-dessous est le code pour montrer comment je fais affaire avec ce problème légitime.

LIEN du FORUM: http://www.java-gaming.org/index.php?topic=25685.new

public class SplashScreen implements Screen {

    // Aspect Ratio maintenance
    private static final int VIRTUAL_WIDTH = 640;
    private static final int VIRTUAL_HEIGHT = 480;
    private static final float ASPECT_RATIO = (float) VIRTUAL_WIDTH / (float) VIRTUAL_HEIGHT;

    private Camera camera;
    private Rectangle viewport;
    // ------end------

    MainGame TempMainGame;

    public Texture splashScreen;
    public TextureRegion splashScreenRegion;
    public SpriteBatch splashScreenSprite;

    public SplashScreen(MainGame maingame) {
        TempMainGame = maingame;
    }

    @Override
    public void dispose() {
        splashScreenSprite.dispose();
        splashScreen.dispose();
    }

    @Override
    public void render(float arg0) {
        //----Aspect Ratio maintenance

        // update camera
        camera.update();
        camera.apply(Gdx.gl10);

        // set viewport
        Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
        (int) viewport.width, (int) viewport.height);

        // clear previous frame
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        // DRAW EVERYTHING
        //--maintenance end--

        splashScreenSprite.begin();
        splashScreenSprite.disableBlending();
        splashScreenSprite.draw(splashScreenRegion, 0, 0);
        splashScreenSprite.end();
    }

    @Override
    public void resize(int width, int height) {
        //--Aspect Ratio Maintenance--
        // calculate new viewport
        float aspectRatio = (float)width/(float)height;
        float scale = 1f;
        Vector2 crop = new Vector2(0f, 0f);

        if(aspectRatio > ASPECT_RATIO) {
            scale = (float) height / (float) VIRTUAL_HEIGHT;
            crop.x = (width - VIRTUAL_WIDTH * scale) / 2f;
        } else if(aspectRatio < ASPECT_RATIO) {
            scale = (float) width / (float) VIRTUAL_WIDTH;
            crop.y = (height - VIRTUAL_HEIGHT * scale) / 2f;
        } else {
            scale = (float) width / (float) VIRTUAL_WIDTH;
        }

        float w = (float) VIRTUAL_WIDTH * scale;
        float h = (float) VIRTUAL_HEIGHT * scale;
        viewport = new Rectangle(crop.x, crop.y, w, h);
        //Maintenance ends here--
    }

    @Override
    public void show() {
        camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); //Aspect Ratio Maintenance

        splashScreen = new Texture(Gdx.files.internal("images/splashScreen.png"));
        splashScreenRegion = new TextureRegion(splashScreen, 0, 0, 640, 480);
        splashScreenSprite = new SpriteBatch();

        if(Assets.load()) {
            this.dispose();
            TempMainGame.setScreen(TempMainGame.mainmenu);
        }
    }
}

Mise à JOUR: j'ai récemment appris que libGDX a certains de ses propres fonctionnalités de maintenir les ratios d'aspect que je voudrais discuter ici. Lors de la recherche de l'aspect ratio de la question à travers l'internet, je suis tombé sur plusieurs forums/développeurs qui ont eu ce problème de "Comment maintenir le ratio d'aspect sur différentes tailles d'écran?" L'une des solutions qui a vraiment fonctionné pour moi a été posté ci-dessus.

Plus tard, lorsque je me rendis à la mise en œuvre de l' touchDown() méthodes pour l'écran, j'ai trouvé que, en raison de mise à l'échelle sur les redimensionner, les coordonnées sur lequel j'avais mis en oeuvre touchDown() changerait par une grande quantité. Après avoir travaillé avec un peu de code pour traduire les coordonnées en conformité avec le redimensionnement de l'écran, j'ai réduit ce montant à une grande mesure, mais je n'ai pas réussi à les entretenir avec la broche point de précision. Par exemple, si j'avais mis en oeuvre touchDown() sur une texture, le redimensionnement de l'écran changement de la touchListener sur la texture de la région de quelques pixels vers la droite ou la gauche, selon la redimensionner et ce n'était évidemment pas souhaitable.

Plus tard, je suis venu pour savoir que la scène de classe a sa propre fonctionnalité native de maintenir le ratio d'aspect (boolean stretch = false). Maintenant que j'ai mis en œuvre mon écran à l'aide de la classe stage, le rapport d'aspect est bien maintenu. Cependant sur les redimensionner ou les différentes tailles d'écran, la zone noire qui est généré apparaît toujours sur le côté droit de l'écran; l'écran n'est pas centrée sur ce qui le rend assez moche si la zone noire est substantiel.

Peut tout membre de la communauté m'aider à résoudre ce problème?

50voto

noone Points 8461

Comment le faire de nos jours:

Puisque c'est l'un des plus célèbres questions sur libgdx ici, je vais lui donner un peu de mise à jour:

Avec la dernière version (nightly build/prochaine version 1.0) libgdx introduite Viewport pour gérer ce problème. Il est beaucoup plus facile à utiliser et la mise à l'échelle de la stratégie est enfichables, ce qui signifie une seule ligne peut changer le comportement, et vous pouvez jouer autour de laquelle l'un s'adapte à votre jeu la meilleure.

Tout ce que vous devez savoir à ce sujet peuvent être trouvées ici.

24voto

Mohammad Rafay Aleem Points 1384

Comme SteveBlack posté le lien de la question qui a été rapporté dans la scène de la classe, j'y suis allé juste pour découvrir que le problème (qui n'était pas vraiment ma question) a été résolu dans les dernières nightlies.

Après des recherches ici et là sur internet pour la question j'ai eu, je ne pouvais pas trouver toutes les solutions ont donc décidé de contacter la personne qui a signalé le bug directement. Après cela, il me répondit sur libgdx forums et je suis redevable à lui pour son aide, pour moi. Voici le lien

C'était une seule ligne de code et tout ce que vous avez à faire est de:

Dans le resize() methond:

stage.setViewport(640, 480, false);
stage.getCamera().position.set(640/2, 480/2, 0);

Où 640 X 480 est la résolution de votre TextureRegion pour décrire l'aspect ratio. Si votre TextureRegion taille 320 X 240, puis les deux arguments doivent être modifiés à la nouvelle résolution de faire le tour.

Lien vers le profil de la personne qui a effectivement résolu mon problème

7voto

Steve Blackwell Points 3741

Les barres noires sur la gauche/droite ou haut/bas à l'air mieux que juste de distorsion de l'ensemble de la scène à l'écran. Si vous ciblez un rapport d'aspect, c'est dans le milieu de la possible plages (4:3 est probablement faible en fin de compte, le 16:9 est probablement haut de gamme), puis les barres doivent rester petit pour la plupart des appareils. Cela vous permet aussi d'utiliser la plupart de l'écran, même sur de plus grands écrans, et vous avez déjà de ce type de code il est donc assez facile. Il serait encore plus beau si c'était juste une option intégrée dans libgdx.

Mais, je pense que la meilleure approche est d'utiliser la totalité de l'écran. Je n'ai pas fait encore, mais il va être l'approche que je prends pour mon prochain projet. L'idée est que si quelqu'un a un écran plus large, ils doivent en voir plus sur les côtés. Chris Pruett parle de comment faire cela dans un de ses discours (lien à repérer dans parlez- en fait, le tout est vraiment très bien). L'idée est de faire évoluer la hauteur, puis définissez votre fenêtre assez large pour s'adapter à l'écran. OpenGL doit prendre soin d'afficher le reste. La façon dont il le fait, c'est ici.

Pour libgdx, peut-être il ya un moyen facile de faire cela avec scene2d par le déplacement de la caméra au-dessus de la scène, mais je n'ai jamais réellement travaillé avec scene2d. Dans tous les cas, l'exécution de l'application en tant que natif fenêtre redimensionnable est un moyen beaucoup plus facile de tester plusieurs tailles d'écran que la création d'un groupe de AVDs.

5voto

NateS Points 1528

Consultez la dernière partie de la section Viewport dans la documentation officielle: https://code.google.com/p/libgdx/wiki/scene2d#Viewport.

3voto

Doran Points 1229

Le ResolutionFileResolver classe permet de résoudre les noms de fichiers à la meilleure résolution. Je crois que ce sera le travail avec différents formats ainsi, à condition que vous avez créé pour les sprites ces proportions. Il y a un exemple d'utilisation dans le AssetManagerTest.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X