2013-09-01 25 views
13

Desidero rendere un pulsante selezionabile, ma non funziona: sembra che sia necessario utilizzare unproject() ma non riesco a capire come. Il codice in questione è:Utilizzo di unProject correttamente in Java Libgdx

Texture playButtonImage; 
SpriteBatch batch; 
ClickListener clickListener; 
Rectangle playButtonRectangle; 
Vector2 touchPos; 
OrthographicCamera camera; 

@Override 
public void show() { 
    playButtonImage = new Texture(Gdx.files.internal("PlayButton.png")); 

    camera = new OrthographicCamera(); 
    camera.setToOrtho(false, 800, 480); 
    batch = new SpriteBatch(); 

    playButtonRectangle = new Rectangle(); 
    playButtonRectangle.x = 400; 
    playButtonRectangle.y = 250; 
    playButtonRectangle.width = 128; 
    playButtonRectangle.height = 64; 
} 

@Override 
public void render(float delta) { 
    Gdx.gl.glClearColor(0, 0, 0.2f, 1); 
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

    camera.update(); 
    batch.setProjectionMatrix(camera.combined); 

    batch.begin(); 
    batch.draw(playButtonImage, playButtonRectangle.x, playButtonRectangle.y); 
    batch.end(); 

    if (Gdx.input.isTouched()) { 
     Vector2 touchPos = new Vector2(); 
     touchPos.set(Gdx.input.getX(), Gdx.input.getY()); 


     if (playButtonRectangle.contains(touchPos)) { 
      batch.begin(); 
      batch.draw(playButtonImage, 1, 1); 
      batch.end(); 
     } 
    } 
} 
+0

È possibile che la coordinata dello schermo (0,0) sia in alto a sinistra, ma la fotocamera ha coordinate (0,0) in basso a sinistra. Cosa succede se usi Gdx.input.getY() * - 1? – Ryan

risposta

11

In generale si utilizza camera.unproject(Vector) per trasformare le coordinate lo schermo da un clic o touch al mondo di gioco. Questo è necessario perché l'origine non è necessariamente la stessa e utilizzando la fotocamera puoi anche ingrandire e rimpicciolire, spostarti, ruotare e così via. Unprojecting si prenderà cura di tutto ciò e ti darà le coordinate del mondo di gioco corrispondenti alla posizione dei puntatori.

Nel tuo esempio sarebbe andata così:

Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); 
camera.unproject(touchPos); 

Avendo questo detto non si dovrebbe effettivamente fare questa operazione manualmente UI. Libgdx ha anche alcune funzionalità dell'interfaccia utente spedite che è chiamata Stage (vedere this). Sono già disponibili molti widget (vedere this). Usano gli skin (puoi ottenere uno di base da here, hai bisogno di tutti i file di uiskin *). Eseguono automaticamente l'inoltro degli input al cosiddetto Actors, ad es. un pulsante e hai solo bisogno di implementare la gestione di quegli eventi.

+2

Come indicato nella mia risposta, l'inizializzazione di un nuovo oggetto Vector3 su ogni frame quando viene toccata sta introducendo un sacco di overhead. I cicli GC sono pesanti soprattutto su applicazioni critiche nel tempo come i giochi (anche peggio sui dispositivi mobili e libgdx è progettato anche per i dispositivi mobili) – laubed

+0

È anche possibile utilizzare Pool per risolvere il problema di inizializzare un nuovo Vector3. – bazola

0

quando mai u bisogno di un punto di contatto dall'utente e per convertire i punti di contatto a fotocamera u bisogno di unproject loro di coordinate fotocamera telecamera coordinate

camera.unproject(touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0)); 
1
@Override 
public void render(float delta) { 
Gdx.gl.glClearColor(0, 0, 0.2f, 1); 
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

camera.update(); 
batch.setProjectionMatrix(camera.combined); 

batch.begin(); 
batch.draw(playButtonImage, playButtonRectangle.x, playButtonRectangle.y); 
batch.end(); 

if (Gdx.input.isTouched()) { 
    Vector3 touchPos = new Vector3(); 
    touchPos.set(Gdx.input.getX(), Gdx.input.getY(),0); 
    camera.unproject(touchPos); 


    if (playButtonRectangle.contains(touchPos.x, touchPos.y)) { 
     batch.begin(); 
     batch.draw(playButtonImage, 1, 1); 
     batch.end(); 
    } 
    } 
    } 
3

con camera.unproject (Vector3); puoi tradurre le coordinate dello schermo in coordinate del mondo di gioco.

Vector3 tmpCoords = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); 
camera.unproject(tmpCoords); 

tmpCoords.x //is now the touched X coordinate in the game world coordinate system 
tmpCoords.y //is now the touched Y coordinate in the game world coordinate system. 

In aggiunta a ciò è meglio norma definire una tmpVector come campo di un'istanza di un oggetto Vector3 sola volta. Puoi quindi fare lo stesso con il metodo .set().

tmpCoords.set(Gdx.input.getX(), Gdx.input.getY(), 0); 
camera.unproject(tmpCoords); 

tmpCoords.x //is now the touched X coordinate in the game world coordinate system 
tmpCoords.y //is now the touched Y coordinate in the game world coordinate system. 

Pertanto, è possibile ridurre la creazione dell'oggetto e rimuovere le chiamate GC non necessarie che portano al microlag.