Java/libGDX - Actions.fadeIn() 和 Actions.fadeOut() 的问题

Java/libGDX - issues with Actions.fadeIn() and Actions.fadeOut()

这是我第一次发帖,我是自学的,所以请多多包涵!

我一直在 libGDX 使用游戏和屏幕 类 构建一个炸弹人复制游戏:

public class Main extends Game {
...

@Override
public void create() {
    levelScreen = new LevelScreen(playerCount, new int[playerCount]);
    levelScreen.level.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(2f)));
    this.setScreen(levelScreen);
}

但是当游戏启动时没有淡入淡出效果。

public class LevelScreen implements Screen {
...

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 0.1f, 0.5f, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    level.act();
    level.draw();
    batch.end();
}

我希望这个 levelScreen 从黑色淡入,但它没有!

当回合结束时,我想从这个关卡屏幕淡出到黑色,然后从黑色淡入到 trophyScreen:

(来自主要 Class)

@Override
public void render() {

    super.render();

        if (endRoundTimer <= 0) {
            trophyScreen = new TrophyScreen(playerCount, levelScreen.getScore());
            levelScreen.level.addAction(Actions.sequence(Actions.fadeOut(1), Actions.run(new Runnable() {
                @Override
                public void run() {
                    setScreen(trophyScreen);
                }
            })));
    }
}

我试过在 TrophyScreen 中使用 show() 方法:

public class TrophyScreen implements Screen {
...
@Override
public void show()  {
    stage.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(1)));
}

我进行了大量搜索并尝试了各种方法,但没有任何乐趣。我确定我在 draw() 或 render() 方法中的某处遗漏了一些阻止淡入淡出动作发生的东西。

更新 1

@Override public void draw() { 
super.draw();
if (roundOver) {
this.getBatch().begin(); String s = String.format("%s", message);
font_text.draw(this.getBatch(), s, (90 + (2 * 30)), (this.getHeight() / 2));
this.getBatch().end();
}

我假设 level 是扩展 Stage 的 class 的对象,并且您正在舞台内创建一个控件,这很奇怪。您没有为 font_text 应用颜色,我认为它是 BitmapFont

解决方法,奇怪的方法

如果您想以这种方式进行操作,您将需要类似的东西:

@Override public void draw() {
    super.draw();
    if (roundOver) {
        getBatch().begin();
        String s = String.format("%s", message);
        font_text.setColor(getRoot().getColor())
        font_text.draw(this.getBatch(), s, (90 + (2 * 30)), (this.getHeight() / 2));
        getBatch().end();
    }
}

getRoot() 从 Stage 中获取 Group,我们这样做,因为应用于 Stage 的每个动作实际上都应用于此 Group root 元素。我们获取颜色(具有 alpha 通道)并将颜色复制到 bitmapFont。

这个解决方案很奇怪,因为您实际上是在 Stage 中创建了一个 Label。没意义,演员是在台上演的,不是在台上演的

解决办法,好办法

你想画文字,对吧?因此,只需使用 Label 即可,它是一个显示文本的演员。演员为您做事:

stage = new Stage();
Label.LabelStyle labelStyle = new Label.LabelStyle(bitmapFont, Color.WHITE);
Label label = new Label("Hi, I am a label!", labelStyle);
stage.addActor(label);

然后你可以应用动作,它们会很好地工作(每个演员都可以应用自己的动作)。

stage.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(5)));
label.addAction(Actions.moveBy(0, 300, 15));

有很多不同的参与者,例如 TextButton、Image、ScrollPane。它们是可定制的,易于管理,并且可以集成到组和表中。

输出:

要使淡入淡出作用于 actors,他们必须在 draw 方法中正确应用自己颜色的 alpha。为了使整个层次结构的对象同时淡出,它们还必须应用 draw 方法签名中的 parentAlpha 参数。

所以您在任何自定义 Actor 子类中的绘制方法应该如下所示:

public void draw (Batch batch, float parentAlpha) {
    Color color = getColor();
    batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
    //..do drawing
}

如果您在 Actor 中使用 Sprite 而不是 TextureRegion(由于冗余,我不推荐这样做),您必须将颜色应用于 Sprite 而不是 Batch。

请注意,这种淡化整个游戏的方法不是 "clean" 淡化。当父 alpha 在淡入淡出期间小于 1 时,任何与其他 actor 重叠的 actor 将相互显示。提供干净外观的替代方法是在整个场景上绘制背景(或黑色)的副本并将其淡化。

更好的方法是先在所有内容上绘制黑色图像,这样您就不必弄乱每个场景对象的 alpha。使用分层来做到这一点。 This post 可能会有帮助。

然后您可以控制它的 alpha 通道,在取消暂停游戏操作之前将其渲染更改为 0 以恢复其绘制周期。在舞台结束时重新激活它以获得淡出效果。

谢谢cray,这样更好。