使用libgdx逐步显示文本

时间:2013-08-16 16:51:21

标签: java label libgdx

我正在寻找一种用libgdx逐步显示文本的方法,但是我找不到按照我想要的方式完成它的方法。这是我做的:

  • 我有一个文本标签,定期更新以显示不同的文本。标签设置为setWrap(true);setAlignment(Align.center);
  • 每次我更改标签的文本时,我都会使用我自己构建的自定义操作

    public class DisplayTextAction extends TemporalAction{
        private CharSequence completeText;
    
        @Override
        protected void update(float percent) {
            ((Label)actor).setText(
                completeText.subSequence(
                    0,
                    (int)Math.round(completeText.length()*percent));
        }
    
        public void setText(String newText){
            completeText = newText;
        }
    }
    
  • 每次文本更新,我都会从池中调用操作,更改文本并将操作添加到标签中。

这是我的问题:这不能按照我想要的方式使用居中和包装文本。

当文本未居中(点代表空格)时会发生这种情况:

|h........|
|hel......|
|hello....|

(按预期工作)

当文本居中时会发生这种情况:

|....h....|
|...hel...|
|..hello..|

这就是我希望它表现的方式:

|..h......|
|..hel....|
|..hello..|

我最初的想法是使用2组字符串,一组是可见文本,一组是不可见的,用作“填充”。我想出了类似的东西:

CharSequence visibleText = completeText.subSequence(
    0,
    (int)Math.round(completeText.length()*percent));
CharSequence invisibleText = completeText.subSequence(
    (int)Math.round(completeText.length()*percent),
    completeText.length());

所以我有两组字符串,但我找不到显示两种不同字体的方法(一种是可见的,另一种是相同但字母为0的字体)或同一标签中的样式Libgdx。

我被困了,我不知道我的方法是否合适,或者我是否应该研究一些完全不同的方法,如果我的方法是正确的,我不知道如何使用libgdx工具来跟进它

编辑:

我遵循了Jyro117的指示,我可以取得很大的进步,但是我无法在多行上使用中心文本。

想象一下这个文字:

|all those lines are|
|..for a very long..|
|........text.......|

它必须像这样显示

|all th.............|
|...................|
|...................|

|all those line.....|
|...................|
|...................|

|all those lines are|
|..for a ve.........|
|...................|

|all those lines are|
|..for a very long..|
|........text.......|

Jyro117的解决方案提供了

|all those lines are|
|for a very long....|
|text...............|

正确显示。

|...................|
|......all tho......|
|...................|

|...................|
|...all those lin...|
|...................|

|all those lines are|
|......for a v......|
|...................|

1 个答案:

答案 0 :(得分:4)

您的解决方案过于复杂。您真正需要的是在添加所有文本时确定标签的大小。确定后,将标签大小锁定到这些尺寸,将其放在扩展的表格内以填充其周围区域,然后使用操作更新标签。 (您可以使用池和所需的,但为了简单起见,我将其留在下面的代码中。)

你必须明显地将代码改编为你的代码,但是这为你提供了我的意思的代码参考。

以下是一种执行此操作的代码段:

stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
Gdx.input.setInputProcessor(stage);

uiSkin = new Skin(Gdx.files.internal("skin/uiskin.json"));

Table fullScreenTable = new Table();
fullScreenTable.setFillParent(true);

final String message = "hello";
final Label progressLabel = new Label(message, this.uiSkin);
final TextBounds bounds = progressLabel.getTextBounds(); // Get libgdx to calc the bounds
final float width = bounds.width;
final float height = bounds.height;
progressLabel.setText(""); // clear the text since we want to fill it later
progressLabel.setAlignment(Align.CENTER | Align.TOP); // Center the text

Table progressTable = new Table();
progressTable.add(progressLabel).expand().size(width, height).pad(10);

final float duration = 3.0f;

final TextButton button = new TextButton("Go!", this.uiSkin);
button.addListener(new ClickListener() {
    @Override public void clicked(InputEvent event, float x, float y) {
        progressLabel.addAction(new TemporalAction(duration){
            LabelFormatter formatter = new LabelFormatter(message);                 
            @Override protected void update(float percent) {
                progressLabel.setText(formatter.getText(percent));
            }
        }); 
    }
});
stage.addActor(button);

fullScreenTable.add(progressTable);
fullScreenTable.row();
fullScreenTable.add(button);

stage.addActor(fullScreenTable);

修改

添加了代码以居中和顶部对齐标签中的文字。还添加了代码以填充末尾的空格以允许正确对齐。注意:仅对单倍间距字体有用。

class LabelFormatter {
    private final int textLength;
    private final String[] data;
    private final StringBuilder textBuilder;

    LabelFormatter(String text) {
        this.textBuilder = new StringBuilder();
        this.data = text.split("\n");
        int temp = 0;
        for (int i = 0 ; i < data.length; i++) {
            temp += data[i].length();
        }
        textLength = temp;
    }

    String getText(float percent) {
        textBuilder.delete(0, textBuilder.length());
        int current = Math.round(percent * textLength);

        for (final String row : data) {
            current -= row.length();
            if (current >= 0) {
                textBuilder.append(row);
                if (current != 0) {
                    textBuilder.append('\n');
                }
            } else {
                textBuilder.append(row.substring(0, row.length() + current));

                // Back fill spaces for partial line
                for (int i = 0; i < -current; i++) {
                    textBuilder.append(' ');
                }
            }

            if (current <= 0) {
                break;
            }
        }

        return textBuilder.toString();
    }
}