2013-09-01 13 views
13

Chcę zrobić kliknięcie przycisku, ale to nie działa - wydaje mi się, że potrzebuję użyć unproject(), ale nie wiem, jak to zrobić. Kod w pytaniu:Prawidłowe używanie UnProject w Javie 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

Możliwe, że współrzędna ekranu (0,0) znajduje się w lewym górnym rogu, ale kamera ma współrzędne (0,0) w lewym dolnym rogu. Co się stanie, jeśli użyjesz Gdx.input.getY() * - 1? – Ryan

Odpowiedz

11

W ogóle użyć camera.unproject(Vector) przekształcić współrzędne ekran z kliknięciem lub naciśnięciem na swój świat gry. Jest to konieczne, ponieważ pochodzenie niekoniecznie jest takie samo i za pomocą aparatu można również powiększać i pomniejszać, poruszać się, obracać i tak dalej. Unprojecting zajmie się tym wszystkim i zapewni współrzędne twojego świata gry odpowiadające pozycji wskaźników.

W przykładzie byłoby to tak:

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

Mając to powiedział, że nie powinien rzeczywiście zrobić to zadanie UI ręcznie. Libgdx ma również pewną funkcjonalność interfejsu użytkownika, która nazywa się Stage (patrz this). Istnieje już wiele widżetów (patrz: this). Używają skórek (można uzyskać podstawowy od here, potrzebujesz wszystkich plików uiskin. *). Automatycznie przekazują inputevents do tak zwanego Actors, np. przycisk i wystarczy zaimplementować obsługę tych zdarzeń.

+2

Jak stwierdzono w mojej odpowiedzi inicjowanie nowego obiektu Vector3 na każdej klatce po dotknięciu wprowadza wiele narzutów. Cykle GC są ciężkie, szczególnie w aplikacjach o krytycznym czasie, takich jak gry (jeszcze gorzej na urządzeniach mobilnych, a libgdx jest również przeznaczony do mobilnego użytku). – laubed

+0

Możesz także użyć Puli, aby obejść problem inicjowania nowego Vector3. – bazola

0

gdy kiedykolwiek u trzeba dotykowy punkt z użytkownikiem i przekonwertować te punkty styku do kamery u trzeba je unproject do kamery przez współrzędne kamery współrzędne

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

z camera.unproject (Vector3); możesz przetłumaczyć współrzędne ekranu na współrzędne świata gry.

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. 

Oprócz tego najlepiej jest zdefiniować tmpVector jako pole i utworzyć instancję obiektu Vector3 tylko raz. Następnie możesz zrobić to samo za pomocą metody .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. 

Dlatego redukujesz tworzenie obiektów i usuwasz niepotrzebne wywołania GC, które prowadzą do mikropasków.

Powiązane problemy