web-dev-qa-db-fra.com

Modification du système de coordonnées dans LibGDX (Java)

LibGDX a un système de coordonnées où (0,0) est en bas à gauche. (comme cette image: http://i.stack.imgur.com/jVrJ0.png )

Cela me fait battre la tête contre un mur, principalement parce que je porte un jeu que j'avais déjà fait avec le système de coordonnées habituel (où 0,0 est dans le coin supérieur gauche).

Ma question: Existe-t-il un moyen simple de changer ce système de coordonnées?

55
Sosavpm

Si vous utilisez une caméra (ce que vous devriez) changer le système de coordonnées est assez simple:

camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

Si vous utilisez TextureRegions et/ou un TextureAtlas, tout ce que vous devez faire en plus de cela est d'appeler region.flip (false, true).

Les raisons pour lesquelles nous utilisons y-up par défaut (que vous pouvez facilement modifier comme illustré ci-dessus) sont les suivantes:

  • votre code de simulation utilisera très probablement un système de coordonnées euclidiennes standard avec y-up
  • si vous allez en 3D, vous avez y-up
  • Le système de coordonnées par défaut est un système droitier dans OpenGL, avec y-up. Vous pouvez bien sûr facilement changer cela avec de la magie matricielle.

Les deux seuls endroits dans libgdx où nous utilisons y-down sont:

  • Coordonnées Pixmap (origine en haut à gauche, y-bas)
  • Toucher les coordonnées des événements qui sont données dans les coordonnées de la fenêtre (origine en haut à gauche, y-bas)

Encore une fois, vous pouvez facilement changer le système de coordonnées utilisé en celui que vous voulez en utilisant soit la caméra, soit un tout petit peu de calcul matriciel.

118
badlogic

Juste pour développer un peu ce que badlogic a dit ci-dessus, si vous utilisez un TextureAtlas (avec TextureRegions), vous devez les retourner, comme l'a dit badlogic, en plus du travail de la caméra. Si vous utilisez un TextureAtlas, vous pouvez utiliser ce code juste après avoir chargé votre atlas:

String textureFile = "data/textures.txt";  
atlas = new TextureAtlas(Gdx.files.internal(textureFile), Gdx.files.internal("data"));  
// Let's flip all the regions.  Required for y=0 is TOP
Array<AtlasRegion> tr = atlas.getRegions();      
for (int i = 0; i < tr.size; i++) {
  TextureRegion t = tr.get(i);
  t.flip(false, true);
}
9
Richard

Si vous souhaitez masquer la transformation et ne pas y penser après l'avoir configurée une fois, vous pouvez créer une classe qui hérite de toutes les fonctionnalités dont vous avez besoin, mais transforme d'abord les coordonnées avant de la passer à la fonction de sa classe parente. Malheureusement, cela prendrait beaucoup de temps.

Vous pouvez également créer une méthode qui fait le simple y' = height - y transformation sur l'ensemble Coordinate objet (ou tout ce que vous utilisez), et appelez-le une fois avant chaque opération.

6
bdares

Bibliothèque graphique intéressante, je dirais. J'ai trouvé cette évaluation à partir du lien ci-dessous:

Un autre problème était que différents systèmes de coordonnées étaient utilisés dans différentes parties de Libgdx. Parfois, l'origine des axes était dans le coin inférieur gauche, l'axe y pointant vers le haut et parfois dans le coin supérieur gauche du Sprite pointant vers le bas. Lors du dessin des maillages, l'origine était même au centre de l'écran. Cela a causé pas mal de confusion et du travail supplémentaire pour que tout soit bien placé à l'écran.

http://www.csc.kth.se/utbildning/kandidatexjobb/datateknik/2011/rapport/ahmed_rakiv_OCH_aule_jonas_K11072.pdf

5
ee.

Je viens de créer une classe qui étend SpriteBatch qui remplace certaines méthodes en ajoutant y = Gdx.graphics.getHeight() - y - height. Simple mais efficace.

1
Ajay

Je ne sais pas si cela aide quelqu'un ou non, mais j'ai pu obtenir des textures et les polices s'affichent correctement en utilisant le système de coordonnées inversé suggéré via OrthographicCamera. Voici ce que j'ai fait:

private SpriteBatch batch;
private BitmapFont font;
private OrthographicCamera cam;
private Texture tex;

@Override
public void create () {
    batch = new SpriteBatch();

    font = new BitmapFont(true);
    font.setColor(Color.WHITE);

    cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    cam.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    tex = new Texture("badlogic.jpg");
}

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

@Override
public void render () {
    cam.update();
    batch.setProjectionMatrix(cam.combined);

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();

    font.draw(batch, "Test", 50, 50);
    batch.draw(tex, 100, 100, tex.getWidth(), tex.getHeight(), 0, 0, tex.getWidth(), tex.getHeight(), false, true);

    batch.end();
}

Les choses importantes à noter sont:

  • Le constructeur BitmapFont, le booléen retourne la police
  • Pour batch.draw (), vous devez utiliser tous ces paramètres car vous avez besoin d'un flipY booléen à la fin pour inverser la texture (je peux étendre SpriteBatch ou créer une méthode utilitaire pour éviter de passer autant de paramètres tout le temps.)
  • Remarquez batch.setProjectionMatrix (cam.combined); dans render ()

Maintenant, nous verrons si je suis de retour ici plus tard ce soir pour faire des modifications afin de résoudre tout autre problème ou découverte en faisant tout cela. :)

0
User