在libGDX中获取表中Actor的Stage坐标 [英] Getting Stage coordinates of Actor in Table in libGDX

查看:122
本文介绍了在libGDX中获取表中Actor的Stage坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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的坐标,在这种情况下是左按钮,然后我可以将泡泡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.

这两个按钮被添加到一个表格如下:

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

这给了我(按照sysouts的顺序):[0.0,0.0]和[40.0, 130.0。最后一个位置实际上是表格的位置,它填充了屏幕的蓝色区域。所以这个位置显然错过了Table放置Actor的功能,并且无法使用(因为我最终得到了Table的位置)。

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).

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

(I've also tried using t.localToStageCoordinates here, t being the Table. Same results.)

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

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

不幸的是,这给了我相同的信息。 sysouts提供以下内容:

Unfortunately, this gives me the same. The sysouts gives the following:

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.

我该怎么做?

推荐答案

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

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).

您需要做的就是:

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

你做错了是试图得到演员的位置相对于表(通过使用actor.getX()和actor.getY()),然后将该位置转换为舞台。这将最终为您提供表的位置,因为它将添加actor的位置。你真正想知道你的演员里面的新Vector2(0,0)在哪里。这告诉你演员的左下角在哪里。如果你想要左上角你会使用新的Vector2(0,actor.getHeight()),以及其他角落的类似方式。

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.

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

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

单击btnLab一次,单击btnSea一次然后关闭窗口,输出:

When clicking btnLab once, clicking btnSea once and then closing the window, outputs:

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消息,因为它可以为您提供舞台上演员的位置。

As you can see you want the "ZeroStage" message because that gives you the location of the actor on the stage.

这篇关于在libGDX中获取表中Actor的Stage坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆