Modifica del sistema di coordinate in LibGDX (Java)

LibGDX ha un sistema di coordinate dove (0,0) è in basso a sinistra. (come questa immagine: http://sofit.miximages.com/java/jVrJ0.png )

Questo mi fa battere la testa contro un muro, principalmente perché sto facendo il porting di un gioco che avevo già fatto con il solito sistema di coordinate (dove 0,0 è nell’angolo in alto a sinistra).

La mia domanda: c’è un modo semplice per cambiare questo sistema di coordinate?

Se usi una macchina fotografica (che dovresti) cambiare il sistema di coordinate è piuttosto semplice:

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

Se usi TextureRegions e / o TextureAtlas, tutto ciò che devi fare in aggiunta a ciò è chiamare region.flip (false, true).

I motivi per cui utilizziamo y-up di default (che puoi facilmente modificare come illustrato sopra) sono i seguenti:

  • molto probabilmente il tuo codice di simulazione usa un sistema di coordinate euclidee standard con y-up
  • se vai in 3D, hai y-up
  • Il sistema di coordinate di default è di destra in OpenGL, con y-up. Ovviamente puoi facilmente cambiarlo con qualche magia di matrice.

Gli unici due posti in libgdx dove usiamo y-down sono:

  • Coordinate Pixmap (superiore in alto a sinistra, y in basso)
  • Toccare le coordinate dell’evento che vengono fornite nelle coordinate della finestra (superiore in alto a sinistra, y in basso)

Di nuovo, puoi facilmente cambiare il sistema di coordinate usato con quello che vuoi usando la fotocamera o un piccolo frammento di matematica matriciale.

Solo per espandere un po ‘quello che diceva la badlogic sopra, se stai usando un TextureAtlas (con TextureRegions) devi capovolgerli, come diceva la badlogic, oltre al lavoro della fotocamera. Se stai usando TextureAtlas, puoi usare questo codice subito dopo aver caricato il tuo atlante:

 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 tr = atlas.getRegions(); for (int i = 0; i < tr.size; i++) { TextureRegion t = tr.get(i); t.flip(false, true); } 

Se si desidera hide la trasformazione e non pensarci dopo averla impostata una volta, è ansible creare una class che eredita tutte le funzionalità necessarie, ma prima trasforma le coordinate prima di passarla alla funzione della class genitore. Sfortunatamente, questo richiederebbe molto tempo.

In alternativa, puoi fare un metodo che esegue la semplice trasformazione y' = height - y sull’intero object Coordinate (o qualunque cosa tu stia utilizzando), e chiamalo una volta prima di ogni operazione.

Interessante libreria grafica, direi. Ho trovato questa valutazione dal link sottostante:

Un altro problema era che diversi sistemi di coordinate erano usati in diverse parti di Libgdx. A volte l’origine degli assi era nell’angolo in basso a sinistra con l’asse y rivolto verso l’alto e talvolta nell’angolo in alto a sinistra dello sprite rivolto verso il basso. Quando si disegnavano le Mesh, l’origine era persino al centro dello schermo. Ciò ha causato un po ‘di confusione e lavoro extra per ottenere tutto nel posto giusto sullo schermo.

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

Ho appena creato una class che estende SpriteBatch che sovrasta alcuni metodi aggiungendo y = Gdx.graphics.getHeight() - y - height . Semplice ma efficace.

Non sono sicuro se questo aiuti qualcuno o meno, ma sono riuscito a ottenere trame e font in modo corretto utilizzando il sistema di coordinate capovolto suggerito tramite OrthographicCamera. Ecco cosa ho fatto:

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

Le cose importanti da notare sono:

  • Il costruttore BitmapFont, il booleano capovolge il carattere
  • Per batch.draw () è necessario utilizzare tutti quei parametri perché è necessario un flipY booleano alla fine per capovolgere la trama (potrei estendere SpriteBatch o fare un metodo di utilità per evitare di passare così tanti parametri tutto il tempo).
  • Notare batch.setProjectionMatrix (cam.combined); in render ()

Ora vedremo se tornerò qui più tardi stasera a fare modifiche per risolvere qualsiasi altro problema o scoperta con tutto ciò. 🙂