Java 在 libGDX 中获取表中 Actor 的舞台坐标
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18075414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting Stage coordinates of Actor in Table in libGDX
提问by Erlend D.
I want to create a floating help bubble to introduce the basic functioning of my game. This bubble should float above the Actor I want it to explain, like shown in the picture below.
我想创建一个浮动帮助气泡来介绍我的游戏的基本功能。这个气泡应该漂浮在我想让它解释的 Actor 上方,如下图所示。
To accomplish this, I want the coordinates of the Actor, in this case the left button, and then I can add the bubble Actor to the Stage in front of everything else. The last part is easy enough, but I'm struggling with retrieving the actual coordinates of the button, as it is in a table.
为了实现这一点,我需要 Actor 的坐标,在本例中是左按钮,然后我可以将气泡 Actor 添加到舞台上其他所有东西的前面。最后一部分很容易,但我正在努力检索按钮的实际坐标,因为它在表格中。
The two buttons are added to a Table like this:
这两个按钮被添加到一个表中,如下所示:
t.add(btnLab).expandX().center();
t.add(btnSea).expandX().center();
I've tried the most obvious approach:
我尝试了最明显的方法:
Vector2 loc = new Vector2(a.getX(), a.getY());
System.out.println("Loc: " + loc);
a.localToStageCoordinates(loc);
System.out.println("Loc: " + loc);
This gives me (in the order of the sysouts): [0.0, 0.0] and [40.0, 130.0]. The last position is actually the position of the Table, which fills the blue area of the screen. So this location obviously misses something the Table does to place the Actor, and cannot be used (as I only end up with the location of the Table).
这给了我(按照系统输出的顺序):[0.0, 0.0] 和 [40.0, 130.0]。最后一个位置其实就是Table的位置,填满了屏幕的蓝色区域。所以这个位置显然错过了 Table 用来放置 Actor 的一些东西,并且无法使用(因为我最终只得到了 Table 的位置)。
(I've also tried using t.localToStageCoordinates here, t being the Table. Same results.)
(我也试过在这里使用 t.localToStageCoordinates,t 是表格。相同的结果。)
Another solution I tried was to recursively search through all Parents:
我尝试的另一个解决方案是递归搜索所有父母:
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());
}
Unfortunately, this gives me the same. The sysouts gives the following:
不幸的是,这给了我同样的。sysouts 提供以下内容:
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
So I can't seem to get the actual positions of the Groups/Actors within the Table.
所以我似乎无法获得表格中组/演员的实际位置。
How am I supposed to do this?
我该怎么做?
采纳答案by Jyro117
I think I understand where you got confused. It is actually very simple to get the stage coordinates of an actor (assuming screen aligned, unrotated, unscaled actors).
我想我明白你在哪里困惑了。获取演员的舞台坐标实际上非常简单(假设屏幕对齐、未旋转、未缩放的演员)。
All you need to do is this:
您需要做的就是:
public static Vector2 getStageLocation(Actor actor) {
return actor.localToStageCoordinates(new Vector2(0, 0));
}
What you are doing wrong is trying to get the location of the actor relative to the table (by using actor.getX() and actor.getY()), and then transform that location to the stage. That will end up giving you the location of table because it will be adding the location of the actor. What you really what is to know where point new Vector2(0, 0) inside your actor is. This tells you where the bottom left corner of the actor is. If you want top left you would use new Vector2(0, actor.getHeight()), and the other corners in a similar manner.
您做错的是试图获取演员相对于表的位置(通过使用 actor.getX() 和 actor.getY()),然后将该位置转换到舞台上。这最终会为您提供表的位置,因为它将添加演员的位置。您真正要知道演员内部的 new Vector2(0, 0) 点在哪里。这会告诉您演员的左下角在哪里。如果您想要左上角,您可以使用 new Vector2(0, actor.getHeight()) 和其他角以类似的方式。
Additionally, if you are working with events and want to know the stage location of an event you would simply do the following:
此外,如果您正在处理事件并想知道事件的舞台位置,您只需执行以下操作:
@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());
}
}
For a more complete example look at the following code:
有关更完整的示例,请查看以下代码:
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() {}
}
When clicking btnLab once, clicking btnSea once and then closing the window, outputs:
单击 btnLab 一次,单击 btnSea 一次然后关闭窗口时,输出:
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
As you can see you want the "ZeroStage" message because that gives you the location of the actor on the stage.
如您所见,您需要“ZeroStage”消息,因为它为您提供了演员在舞台上的位置。