2013-05-13 9 views
11

Ho uno schermo (BaseScreen implementa l'interfaccia Schermo) che rende un'immagine PNG. Al clic dello schermo, sposta il personaggio nella posizione toccata (a scopo di test).libgdx differenze di sistema di coordinate tra il rendering e l'input touch

public class DrawingSpriteScreen extends BaseScreen { 
    private Texture _sourceTexture = null; 
    float x = 0, y = 0; 

    @Override 
    public void create() { 
     _sourceTexture = new Texture(Gdx.files.internal("data/character.png")); 
    } 

    . 
    . 
} 

Durante il rendering dello schermo, se l'utente ha toccato lo schermo, afferro le coordinate del tocco, e quindi utilizzare questi per rendere l'immagine del carattere.

@Override 
public void render(float delta) { 
    if (Gdx.input.justTouched()) { 
     x = Gdx.input.getX(); 
     y = Gdx.input.getY(); 
    } 

    super.getGame().batch.draw(_sourceTexture, x, y); 
} 

Il problema è le coordinate per il disegno della immagine start dalla posizione inferiore sinistra (come indicato nella LibGDX Wiki) e le coordinate per il tocco ingresso inizia dall'angolo in alto a sinistra. Quindi il problema che sto avendo è che clicco in basso a destra, sposta l'immagine in alto a destra. Le mie coordinate potrebbero essere X 675 Y 13, che al tocco sarebbe vicino alla parte superiore dello schermo. Ma il personaggio mostra in basso, poiché le coordinate iniziano da in basso a sinistra.

Perché è cosa? Perché i sistemi di coordinate sono invertiti? Sto usando gli oggetti sbagliati per determinare questo?

risposta

17

Per rilevare la collisione, utilizzo camera.unproject(vector3). Ho impostato vector3 come:

x = Gdx.input.getX();  
y = Gdx.input.getY(); 
z=0; 

Ora mi passano questo vettore in camera.unproject(vector3). Usa x e di questo vettore per disegnare il tuo personaggio.

+1

Ci sono un sacco di tali domande là fuori e un sacco di risposte che dicono che devi fare camera.unproject, ma io quando stavo iniziando con libGDX ho semplicemente non sapevano cosa fare poi (cioè, usare la nuove coordinate vettoriali). Questa è l'unica risposta che ho trovato allora specifica questo, così tante, molte grazie, ottima risposta! –

6

Lo stai facendo bene. Libgdx generalmente fornisce i sistemi di coordinate nel loro formato "nativo" (in questo caso le coordinate native del touch screen e le coordinate OpenGL predefinite). Questo non crea alcuna coerenza, ma significa che la libreria non deve entrare tra te e tutto il resto. La maggior parte dei giochi OpenGL utilizza una telecamera che mappa sullo schermo le coordinate "mondiali" relativamente arbitrarie, quindi le coordinate del mondo/gioco sono spesso molto diverse dalle coordinate dello schermo (quindi la coerenza è impossibile). Vedi Changing the Coordinate System in LibGDX (Java)

Ci sono due modi per aggirare questo problema. Uno è trasformare le coordinate touch. L'altro è usare una fotocamera diversa (una proiezione diversa).

A correggere le coordinate di tocco, è sufficiente sottrarre y dall'altezza dello schermo. È un po 'un trucco. Più in generale si desidera "non proiettare" dallo schermo nel mondo (vedere lo Camera.unproject() variations). Questo è probabilmente il più semplice.

In alternativa, per fissare la telecamera vedere "Changing the Coordinate System in LibGDX (Java)" o this post on the libgdx forum. In pratica si definisce una telecamera personalizzata, e quindi impostare il SpriteBatch da usare che al posto del default .:

// Create a full-screen camera: 
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 
// Set it to an orthographic projection with "y down" (the first boolean parameter) 
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 
camera.update(); 

// Create a full screen sprite renderer and use the above camera 
batch = new SpriteBatch(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 
batch.setProjectionMatrix(camera.combined); 

Mentre fissa i lavori della fotocamera, si tratta di "nuotare controcorrente" un po '. Incontrerai altri renderer (ShapeRenderer, i renderer dei font, ecc.) Che saranno anche impostati di default sulla telecamera "sbagliata" e dovranno essere riparati.

4

Ho avuto lo stesso problema, ho semplicemente fatto questo.

public boolean touchDown(int screenX, int screenY, int pointer, int button) { 

    screenY = (int) (gheight - screenY); 
    return true; 
} 

e ogni volta che si desidera ricevere input dall'utente non utilizzare Gdx.input.getY(); invece utilizzare (Gdx.graphics.getHeight() - Gdx.input.getY()) che ha funzionato per me.

1

Il collegamento seguente illustra questo problema.

Projects the given coords in world space to screen coordinates.

è necessario utilizzare il metodo project(Vector3 worldCoords) in classe com.badlogic.gdx.graphics.Camera.

private Camera camera; 
............ 

@Override 
public boolean touchDown(int screenX, int screenY, int pointer, int button) { 

Creare un'istanza del vettore e inizializzarla con le coordinate del gestore di eventi di input.

Vector3 worldCoors = new Vector3(screenX, screenY, 0); 

Progetti il ​​mondoCentro assegnato nello spazio mondiale alle coordinate dello schermo.

camera.project(worldCoors); 

Utilizzare le coordinate proiettate.

world.hitPoint((int) worldCoors.x, (int) worldCoors.y); 

    OnTouch(); 

    return true; 
}