【问题标题】:Getting Stage coordinates of Actor in Table in libGDX在libGDX中获取Actor的舞台坐标
【发布时间】:2013-08-07 04:16:59
【问题描述】:

我想创建一个浮动帮助气泡来介绍我的游戏的基本功能。这个气泡应该漂浮在我想要解释的 Actor 上方,如下图所示。

为此,我需要 Actor 的坐标,在本例中为左按钮,然后我可以将气泡 Actor 添加到舞台上其他所有内容的前面。最后一部分很简单,但我正在努力检索按钮的实际坐标,因为它在表格中。

这两个按钮被添加到一个表格中,如下所示:

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

我尝试了最明显的方法:

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

这给了我(按系统输出的顺序):[0.0, 0.0] 和 [40.0, 130.0]。最后一个位置其实就是Table的位置,填满了屏幕的蓝色区域。所以这个位置显然遗漏了 Table 用来放置 Actor 的一些东西,并且不能使用(因为我最终只得到了 Table 的位置)。

(我也尝试在这里使用 t.localToStageCoordinates,t 是表格。结果相同。)

我尝试的另一个解决方案是递归搜索所有父母:

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

不幸的是,这给了我同样的结果。 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

所以我似乎无法获得表格中组/演员的实际位置。

我该怎么做?

【问题讨论】:

  • 除了我的回答之外,我想知道您是否试图在第一次渲染演员之前获得演员的位置?如果您在框架有时间正确进行布局之前尝试获取位置,您将获得错误的坐标。在我的示例中,我通过使用事件侦听器在执行布局后获取正确位置来缓解这种情况。
  • 我的Stage 中有一个VerticalGroup 内的Table 内的另一个Table。我遵循了以下答案,但没有奏效。问题最终是在我分配起始表位置之前没有布置元素。该答案中的舞台位置翻译都不是必需的。 table.getX() 为我提供了在布局发生后我需要的舞台位置。
  • @Jyro117 感谢您的提示。我遇到了同样的问题。花了很长时间才意识到我可能计算演员位置太早了。

标签: java coordinates libgdx


【解决方案1】:

我想我明白你在哪里感到困惑。获取演员的舞台坐标实际上非常简单(假设屏幕对齐、未旋转、未缩放演员)。

您需要做的就是:

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

您做错的事情是尝试获取演员相对于桌子的位置(通过使用 actor.getX() 和 actor.getY()),然后将该位置转换为舞台。这将最终为您提供桌子的位置,因为它将添加演员的位置。你真正要知道你的演员内部的新向量2(0,0)点在哪里。这告诉你演员的左下角在哪里。如果你想要左上角,你可以使用 new Vector2(0, actor.getHeight()),并以类似的方式使用其他角。

此外,如果您正在处理活动并想知道活动的舞台位置,您只需执行以下操作:

@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() {}
}

点击一次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

如您所见,您需要“ZeroStage”消息,因为它可以为您提供演员在舞台上的位置。

【讨论】:

  • 问题显示a.getX(), a.getY() 的输出是0,0,所以这不意味着OP 已经完全按照您的建议执行了吗?
  • 我已经用一个完整的例子更新了我的答案,显示 0,0 确实给了你舞台坐标。 OP 可能正在做一些不同的事情来导致他的输出不同。
  • 哈哈,是的,零成功了!那是愚蠢的。感谢您的回答,以及非常全面的回答。
  • hhm,对我不起作用。我有表格里面的图片和舞台里面的表格。我在图像上使用 localToStageCoordinates(new Vector2()) ,但它返回了错误的坐标。我使用 libgdx 1.1.0
  • 这对我有用,但仅在绘制表格和舞台之后。如果我在初始设置期间请求位置,它会返回不寻常的坐标
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 2016-02-10
相关资源
最近更新 更多