2013-08-06 20 views
8

Oyunumun temel işlevini tanıtmak için yüzen bir yardım balonu oluşturmak istiyorum. Bu balon aşağıda açıklandığı gibi, açıklamasını istediğim Oyuncu'nun üzerinde yüzmelidir. Masaüstünde Aktörün Sahne Alanı koordinatlarını alma libGDX

Floating instruction bubble.

bu durumda, ben aktör koordinatlarını istiyorum, sol düğmeye Bunu başarmak için, ve sonra her şey önünde Sahne için kabarcık Erkek Oyuncu ekleyebilir. Son bölüm yeterince kolay, ama bir masadaki gibi düğmenin gerçek koordinatlarını almakta zorlanıyorum.

iki düğme

Böyle bir tablo eklenir:

Vector2 loc = new Vector2(a.getX(), a.getY()); 
System.out.println("Loc: " + loc); 
a.localToStageCoordinates(loc); 
System.out.println("Loc: " + loc); 

Bu (sysouts sırasına göre) bana verir: Ben en bariz yaklaşım denedim

t.add(btnLab).expandX().center(); 
t.add(btnSea).expandX().center(); 

: [0.0, 0.0] ve [40.0, 130.0]. Son konum, aslında ekranın mavi alanını dolduran Tablosun pozisyonudur. Yani bu yer, Tabii ki Aktör'ü yerleştirmek için bir şey yapmaz ve kullanılamaz (sadece Tablonun bulunduğu yerle son bulurum).

(Ben de Tablo olmanın t burada t.localToStageCoordinates kullanarak denedim aynı sonuç..)

Ben ardışık tüm Ebeveynler arama yapmasına oldu çalıştı Başka bir çözüm:

private static Vector2 getLoc(Actor a) { 
    return getLoc(new Vector2(a.getX(), a.getY()), a.getParent()); 
} 

private static Vector2 getLoc(Vector2 loc, Actor g) { 
    System.out.println("Location: " + loc + ", Actor: " + g); 
    loc.x += g.getX(); 
    loc.y += g.getY(); 
    if(g.getParent() == null) return loc; 
    return getLoc(loc, g.getParent()); 
} 

Maalesef Bu bana aynı şeyi veriyor. sysouts verir aşağıdadır:

Location: [0.0:0.0], Actor: Table 40.0,130.0 944.0x508.0 
Location: [40.0:130.0], Actor: Group 0.0,0.0 0.0x0.0 
Location: [40.0:130.0], Actor: Group 0.0,0.0 0.0x0.0 

Yani Tablo içindeki Gruplar/Aktörler gerçek konumlarını almak gibi olamaz.

Bunu nasıl yapacağım?

+1

Cevabımın yanı sıra, aktörler ilk kez işlenmeden önce oyuncu pozisyonunu almaya çalışıp çalışmadığınızı merak ediyorum. Eğer çerçeve, düzeni doğru bir şekilde yapmadan önce yeri bulmaya çalışırsanız, yanlış koordinatları alacaksınız. Örneğimde, düzen gerçekleştirildikten sonra doğru konumu almak için bir olay dinleyicisi kullanarak bunu hafifletirim. – Jyro117

+0

"Sahne Alanı" nda başka bir "Tablo" içinde "VerticalGroup" içinde bir "Tablo" var. Aşağıdaki cevabı takip ettim, ama işe yaramadı. Sorun, başlangıç ​​tablo pozisyonunu belirlemeden önce elemanların yerleştirilmemesiydi. Bu cevapta sahne yeri çevirisinin hiçbiri gerekli değildi. 'table.getX()' düzeni yaptıktan sonra bunu yaptıktan sonra ihtiyaç duyduğum aşamada yeri aldım. – bazola

+0

@ Jyro117 Bu bahşiş için teşekkürler. Aynı sorunu yaşıyordum. Oyuncu pozisyonlarını çok erken hesaplayabildiğimin farkına varmak uzun zaman aldı. – WeirdElfB0y

cevap

20

Sanırım kafanızın nerede olduğunu anlıyorum. Bir aktörün sahne koordinatlarını almak gerçekten çok basittir (ekran hizalanmış, döndürülmemiş, ölçeklenmemiş aktörler varsayılarak).

yapmanız gereken tek şey

şudur:

public static Vector2 getStageLocation(Actor actor) { 
    return actor.localToStageCoordinates(new Vector2(0, 0)); 
} 

Ne tabloya aktör durumuna göre konumunu almaya çalışırken yanlış yapıyoruz (actor.getX() ve actor.getY (kullanarak)) ve sonra bu konumu sahneye dönüştürün. Bu, tablonun yerini size verecektir çünkü oyuncu konumunu ekleyecektir. Gerçekte ne demek olduğunu bilmek nerede aktörünüzün yeni Vector2 (0, 0) noktasıdır. Bu, aktörün sol alt köşesinin nerede olduğunu söyler. Sol üstte isterseniz yeni Vector2 (0, actor.getHeight()) ve diğer köşeleri de benzer şekilde kullanırsınız.

Ayrıca, etkinlikler üzerinde çalışırken ve sadece aşağıdaki yapardın bir olayın sahne konumunu bilmek istiyorum eğer:

: Aşağıdaki kodu bakmak daha eksiksiz Örneğin

@Override public void touchUp(final InputEvent event, final float x, final float y, final int pointer, final int button) { 
    if (pointer == Buttons.LEFT) { 
     Gdx.app.log("Event", "x: " + event.getStageX() + " y: " + event.getStageY()); 
    } 
} 

import com.badlogic.gdx.ApplicationListener; 
import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.math.Vector2; 
import com.badlogic.gdx.scenes.scene2d.InputEvent; 
import com.badlogic.gdx.scenes.scene2d.Stage; 
import com.badlogic.gdx.scenes.scene2d.ui.*; 
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 

public class ActorStage implements ApplicationListener { 
    private Stage stage; 
    private Skin skin; 

    @Override public void create() { 
     Gdx.app.log("CREATE", "App Opening"); 

     this.stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); 
     Gdx.input.setInputProcessor(this.stage); 

     this.skin = new Skin(Gdx.files.internal("skin/uiskin.json")); 
     this.skin.hashCode(); 

     final Table table = new Table(); 
     table.setFillParent(true); 

     final Button btnLab = new TextButton("Lab", skin); 
     final Button btnSea = new TextButton("Sea", skin); 


     setupButton(table, btnLab); 
     setupButton(table, btnSea); 

     this.stage.addActor(table); 

     Gdx.gl20.glClearColor(0f, 0f, 0f, 1); 
     Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); 
    } 

    private void setupButton(Table table, final Button button) { 
     table.add(button).expandX().center(); 

     button.addListener(new ClickListener() { 
      @Override public void clicked(InputEvent event, float x, float y) { 
       Gdx.app.log("XY", "[" + x + ", " + y + "]"); 
       Gdx.app.log("Event", "[" + event.getStageX() + ", " + event.getStageY() + "]"); 
       Gdx.app.log("Actor", "[" + button.getX() + ", " + button.getY() + "]"); 

       Vector2 loc = new Vector2(button.getX(), button.getY()); 
       Vector2 stageLoc = button.localToStageCoordinates(loc); 
       Gdx.app.log("ActorStage", "[" + stageLoc.x + ", " + stageLoc.y + "]"); 

       Vector2 zeroLoc = button.localToStageCoordinates(new Vector2()); 
       Gdx.app.log("ZeroStage", "[" + zeroLoc.x + ", " + zeroLoc.y + "]"); 
      } 
     }); 
    } 

    @Override public void render() { 
     this.stage.act(); 

     Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 
     Gdx.gl20.glEnable(GL20.GL_BLEND); 

     this.stage.draw(); 
    } 

    @Override public void dispose() { 
     Gdx.app.log("DISPOSE", "App Closing"); 
    } 

    @Override public void resize(final int width, final int height) { 
     Gdx.app.log("RESIZE", width + "x" + height); 
     Gdx.gl20.glViewport(0, 0, width, height); 
     this.stage.setViewport(width, height, false); 
    } 

    @Override public void pause() {} 

    @Override public void resume() {} 
} 

pencere, çıkışlar kez btnSea tıklayıp ardından kapanış kez btnLab tıklandığında:

CREATE: App Opening 
RESIZE: 800x600 
XY: [18.0, 13.0] 
Event: [200.0, 296.0] 
Actor: [182.0, 283.0] 
ActorStage: [364.0, 566.0] 
ZeroStage: [182.0, 283.0] 
XY: [6.0, 23.0] 
Event: [588.0, 306.0] 
Actor: [582.0, 283.0] 
ActorStage: [1164.0, 566.0] 
ZeroStage: [582.0, 283.0] 
DISPOSE: App Closing 

Gördüğünüz gibi "ZeroStage" mesajını almak istediğinizde, çünkü bu size sahnenin aktörünün konumunu verir.

+0

Soru, a.getX(), a.getY() 'nin çıktısının' 0,0' olduğunu gösteriyor, bu yüzden OP'nin tam olarak önerdiğiniz şeyi yaptığı anlamına gelmez mi? – DannyMo

+0

Yanıtımı, 0,0 değerinin size sahne koordinatlarını verdiğini gösteren tam bir örnekle güncelledim. OP, çıktısının farklı olması için farklı bir şey yapıyor olabilir. – Jyro117

+0

Haha, evet, sıfırlar hile yaptı! Bu aptalcaydı. Bunun için ve çok kapsamlı cevap için teşekkür ederim. –