【问题标题】:InputListener for BitmapFont used as an Actor does not work in LibGDX用作 Actor 的 BitmapFont 的 InputListener 在 LibGDX 中不起作用
【发布时间】:2016-02-29 15:18:59
【问题描述】:

我设法从 .*ttf 创建了一个文本,现在我有了一个 BitmapFont 对象。我想把它用作演员。在 Actor 的方法 draw() 中,我使用了:

 FontRed.draw(batch, "Some text!", getX(), getY());

显示了文本,但侦听器不起作用。当我试图从 BitmapFont 中获取一个区域时: batch.draw(FontRed.getRegion(), getX(), getY(), getWidth(), getHeight());

我在屏幕上看到了很多奇怪的符号而不是我的文字,但我的听众工作正常。

我认为这与这个事实密切相关,即 spritebatch 是在 BitmapFont 的 draw() 方法中发送的。这是我的完整代码:

public class Text extends Actor {
private BitmapFont FontRed;
private FreeTypeFontGenerator generator;
FreeTypeFontParameter parameter;
String FONT_CHARS = "";

public Text(GameStateManager gsm){
    generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/myfont.ttf"));
    for( int i = 32; i < 127; i++ ) FONT_CHARS += (char)i; 
    for( int i = 1024; i < 1104; i++ ) FONT_CHARS += (char)i;
    parameter = new FreeTypeFontParameter();
    parameter.characters = FONT_CHARS;
    parameter.size = 82;
    parameter.color= Color.RED;
    FontRed = generator.generateFont(parameter);
    generator.dispose();
    setPosition(30, 300);
    setSize(182, 182);
    this.addListener(new Listener(gsm));
}

@Override
public void draw(Batch batch, float parentAlpha) {
    FontRed.draw(batch, "Some text!", getX(), getY());
   // batch.draw(FontRed.getRegion(), getX(), getY(), getWidth(), getHeight());

}

@Override
public void act(float delta) {
}

class Listener extends InputListener {
    GameStateManager gsm;
    Listener(GameStateManager gsm){
        this.gsm = gsm;
    }

    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        event.getListenerActor().setColor(Color.GREEN);
        System.out.println("it works");
        return true;
    }

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
        gsm.push(new PlayState(gsm));
    }
}

}

所以请解释一下为什么当在 BitmapFont 的方法 draw() 中发送 spritebatch 时 Actor 中的列表器不起作用,以及如何从 BitmapFont 制作纹理以便在 batch.draw() 中使用它?

【问题讨论】:

  • 演员的绘制方式完全独立于任何听众,所以一定有其他事情发生。您如何确定侦听器是否在工作?现在你已经设置了actor的颜色,但是你在绘制它时没有使用actor的颜色,所以它是不可见的。您是说“它有效”日志仅在您绘制字体区域时发生?他们没有任何关系。
  • @Tenfour04,设置演员的颜色没关系,我忘了删除它。我的意思是当我画FontRed.draw(batch, "Some text!", getX(), getY());System.out.println("it works"); 不起作用但是当我画batch.draw(FontRed.getRegion(), getX(), getY(), getWidth(), getHeight()); 时,我看到的是愚蠢的符号而不是我的文字,但听众可以工作。你说他们没有关系。但是该怎么办?请帮帮我。
  • 再次检查。如果您查看 Stage 和 Actor 的源代码,您会发现您所描述的内容是不可能的。您必须进行其他更改。

标签: libgdx


【解决方案1】:

正如评论者所提到的,如果您在定义 Actor 边界的 182 x 182 框内单击,则绘制 Actor 的方式与 Listener 是否应该工作无关。当你使用这条线绘制时:

batch.draw(FontRed.getRegion(), getX(), getY(), getWidth(), getHeight());

您正在精确地在 Actor 的区域中绘制定义字体的纹理(这是一种将字体中的每个字符挤压在一起的纹理),因此当您单击可见纹理时,侦听器会触发。当你使用这条线绘制时:

FontRed.draw(batch, "Some text!", getX(), getY());

您正在以与 Actor 的边界无关的方式绘制文本。 BitmapFont .draw() 方法的坐标参数定义文本的左上角,而 Actor 的 x 和 y 坐标定义左下角。当您使用该行代码进行绘制时,文本将绘制在 Actor 的边界之下。如果您点击文本上方,您的 Listener 应该会触发。

如果您想创建一个带有仅在您单击文本本身时触发的侦听器的 Actor,您可以使用 GlyphLayout 来确定使用您的字体绘制的文本的边界,并使用它来设置 Actor 的边界:

GlyphLayout layout = new GlyphLayout(FontRed, "Some text!");
setSize(layout.width, layout.height);

然后,当您绘制文本时,相对于 Actor 的左上角进行绘制:

FontRed.draw("Some text!", getX(), getY(Align.topLeft));

但是,我不建议使用这种方法。如果你想制作一个响应点击的文本对象,我建议你使用 scene2d.ui 中的一个类,例如 Label 或 Button。这些类为您提供了很多控制权,并让您可以轻松地完成诸如给文本添加背景、在文本和 Actor 边界之间添加填充以及在 Actor 内对齐文本等操作。

【讨论】:

  • 非常感谢您这么特别的解释!现在它可以工作了,我想我会听从你关于 Button 和 Label 的建议。
猜你喜欢
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
相关资源
最近更新 更多