2013-05-13 7 views
11

Ich habe einen Bildschirm (BaseScreen implementiert die Bildschirmoberfläche), die ein PNG-Bild rendert. Mit einem Klick auf den Bildschirm bewegt er das Zeichen in die berührte Position (zu Testzwecken).libgdx Koordinatensystem Unterschiede zwischen Rendering und Touch-Eingabe

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

    . 
    . 
} 

Während des Bildschirms Rendering, wenn der Benutzer den Bildschirm berührt, greifen I die Koordinaten der Berührung, und verwenden dann diese das Zeichenbild zu rendern.

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

Die Ausgabe sind, die Koordinaten zum Zeichnen des Bildstarts von der linken unteren Position, und die Koordinaten (wie in der Libgdx Wiki angegeben) für die Berührungseingabe von der oberen linken Ecke beginnt. Das Problem, das ich habe, ist, dass ich unten rechts klicke, es bewegt das Bild nach rechts oben. Meine Koordinaten können X 675 Y 13 sein, was bei Berührung nahe dem oberen Rand des Bildschirms sein würde. Der Charakter zeigt sich jedoch unten, da die Koordinaten von links unten beginnen.

Warum ist was? Warum werden die Koordinatensysteme umgekehrt? Benutze ich die falschen Objekte, um das zu bestimmen?

Antwort

17

Um Kollision zu erkennen verwende ich camera.unproject(vector3). Ich habe vector3 wie:

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

Jetzt habe ich diesen Vektor in camera.unproject(vector3) passieren. Verwenden Sie x und y dieses Vektors, um Ihren Charakter zu zeichnen.

+1

Es gibt viele solche Fragen gibt, und viele Antworten sagen, dass Sie camera.unproject tun müssen, aber ich, wenn ich mit Libgdx Start war ich wusste einfach nicht, was dann zu tun (dh verwenden die neue Vektorkoordinaten). Dies ist die einzige Antwort, die ich damals gefunden habe, die dies angibt, so viele, vielen Dank, großartige Antwort! –

6

Sie machen es richtig. Libgdx stellt im Allgemeinen Koordinatensysteme in ihrem "nativen" Format bereit (in diesem Fall die nativen Touchscreen-Koordinaten und die Standard-OpenGL-Koordinaten). Dies schafft keine Konsistenz, aber es bedeutet, dass die Bibliothek nicht zwischen Sie und alles andere geraten muss. Die meisten OpenGL-Spiele verwenden eine Kamera, die relativ willkürliche "Welt" -Koordinaten auf dem Bildschirm abbildet, so dass sich die Welt-/Spielkoordinaten oft stark von den Bildschirmkoordinaten unterscheiden (Konsistenz ist also unmöglich). Siehe Changing the Coordinate System in LibGDX (Java)

Es gibt zwei Möglichkeiten, die Sie umgehen können. Einer ist Ihre Touch-Koordinaten zu transformieren. Die andere ist, eine andere Kamera zu verwenden (eine andere Projektion).

Um die Touch-Koordinaten zu fixieren, subtrahieren Sie einfach das y von der Bildschirmhöhe. Das ist ein bisschen wie ein Hack. Allgemeiner gesagt, Sie möchten vom Bildschirm in die Welt "unprojecten" (siehe Camera.unproject() variations). Dies ist wahrscheinlich am einfachsten.

Alternativ zu die Kamera fixieren, siehe "Changing the Coordinate System in LibGDX (Java)" oder this post on the libgdx forum. Grundsätzlich Sie eine benutzerdefinierte Kamera definieren und dann die SpriteBatch eingestellt, dass verwenden anstelle der Standard-.:

// 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); 

Während die Kamera funktioniert Fixierung ist es „den Strom schwimmen“ ein wenig. Sie werden andere Renderer (ShapeRenderer, die Schriftart-Renderer, etc.), die auch standardmäßig auf die "falsche" Kamera und müssen behoben werden.

4

Ich hatte das gleiche Problem, ich habe das einfach getan.

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

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

und jedes Mal, wenn Sie Eingaben vom Benutzer nehmen möchten, verwenden Sie nicht Gdx.input.getY(); Verwenden Sie stattdessen (Gdx.graphics.getHeight() - Gdx.input.getY()) das für mich funktioniert hat.

1

Der folgende Link beschreibt dieses Problem.

Projects the given coords in world space to screen coordinates.

Sie benötigen com.badlogic.gdx.graphics.Camera die Methode project(Vector3 worldCoords) in der Klasse zu verwenden.

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

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

eine Instanz des Vektors erstellen und mit den Koordinaten des Eingabeereignisbehandlungsroutine initialisieren.

Projiziert die WorldCoors Welt Koordinaten Koordinaten zu geben.

camera.project(worldCoors); 

Verwendete Koordinaten verwenden.

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

    OnTouch(); 

    return true; 
} 
Verwandte Themen