用作Actor的BitmapFont的InputListener在LibGDX中不起作用

时间:2016-02-29 15:19:00

标签: libgdx

我设法从。* ttf创建一个文本,现在我有一个BitmapFont对象。我想用它作为演员。在Actor`s方法中,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中的listner不起作用,以及如何从BitmapFont中创建一个纹理以在batch.draw()中使用它?

1 个答案:

答案 0 :(得分:0)

正如评论者所提到的,绘制Actor的方式与如果你在定义Actor界限的182 x 182框内单击,监听器是否应该工作无关。当您使用此行绘制时:

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

您正在绘制定义字体的纹理(这是一个纹理,其中字体中的每个字符都压缩在一起)完全在Actor的区域中,因此当您单击可见纹理时,监听器将触发。当您使用此行绘制时:

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

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

如果你想制作一个只有当你点击文本本身时才会触发的监听器的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中对齐文本等操作。