Search code examples
javalibgdxscene2d

LibGDX Actor won't draw Actions


I have the following LibGDX Actor subclass which does not seem to perform any visual Action, but it executes the delayed runnables (I can see all the Gdx.app.log messages after the expected delays).

I'm calling super.act(delta) in my overridden TileActor.act method, and I'm also calling stage.act(); stage.draw() in the Stage class.

These actors display properly, so the only missing thing is the visual actions for scaling/fading.

How can I debug this?

class TileActor extends Actor {
  private TileLogic logic;
  private boolean flipped;
  private enum AnimationState {
    IDLE,
    SCHEDULED,
    PROGRESS,
    COMPLETED
  }
  private AnimationState flippedAnimation;

  private float FLIP_DURATION = 1.05f;

  TileActor(TileLogic logic, BoardRenderer renderer) {
    this.logic = logic;
    flipped = logic.isFlipped();
    flippedAnimation = AnimationState.IDLE;
    column = logic.column;
    row = logic.row;
  }

  void place() {
    setPosition(calculateX(logic.column), calculateY(logic.row));
  }

  private float calculateX(int column) {
    return column * (getWidth() + renderer.TILE_GAP) + renderer.boardXPosition;
  }

  private float calculateY(int row) {
    return (renderer.manager.rows - row - 1) * (getHeight() + renderer.TILE_GAP) + renderer.boardYPosition;
  }

  @Override
  public void draw(Batch batch, float parentAlpha) {
    batch.draw(flipped ? front : back, calculateX(logic.column), calculateY(logic.row), getWidth(), getHeight());
  }

  @Override
  public void act(float delta) {
    super.act(delta);
    if (flippedAnimation == AnimationState.IDLE && flipped != logic.isFlipped()) {
      flippedAnimation = AnimationState.SCHEDULED;
    }
    if (flippedAnimation == AnimationState.SCHEDULED) {
      playFlipAnimation();
    }
    if (flippedAnimation == AnimationState.COMPLETED) {
      flippedAnimation = AnimationState.IDLE;
      Gdx.app.log("TileActor.act", logic.value + (flippedAnimation.name()));
    }
  }

  private void playFlipAnimation() {
    flippedAnimation = AnimationState.PROGRESS;
    Gdx.app.log("TileActor.playFlipAnimation", logic.value + (flippedAnimation.name()));
    addAction(sequence(
      parallel(// This does not happen, at least I can see no scale or fade animation
        scaleTo(1, 0, FLIP_DURATION, Interpolation.pow5),
        fadeOut(FLIP_DURATION, Interpolation.pow5)
      ),
      new Action() {// This is executed as expected, I can see the log message
        @Override
        public boolean act(float delta) {
          flipped = logic.isFlipped();
          Gdx.app.log("TileActor.playFlipAnimation", logic.value + (flipped ? " " : " NOT ") + " flipped");
          return true;
        }
      },
      parallel(// This does not happen, at least I can see no scale or fade animation
        scaleTo(1, 1, FLIP_DURATION, Interpolation.pow5),
        fadeIn(FLIP_DURATION, Interpolation.pow5)
      ),
      new Action() {// This is executed as expected, I can see the log message after the delay
        @Override
        public boolean act(float delta) {
          flippedAnimation = AnimationState.COMPLETED;
          Gdx.app.log("TileActor.playFlipAnimation", logic.value + (flippedAnimation.name()));
          return true;
        }
      }
    ));
  }
}

Solution:

My draw method has to handle the color change and pass on the scale values as well, like this:

@Override
public void draw(Batch batch, float parentAlpha) {
  final Color color = getColor();
  batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
  batch.draw(flipped ? front : back,
    calculateX(logic.column), calculateY(logic.row),
    getOriginX(), getOriginY(),
    getWidth(), getHeight(),
    getScaleX(), getScaleY(),
    getRotation());
}

Solution

  • FadeActions and ColorActions modify the Actor's Color object. You have to apply this color to the batch when drawing.

    @Override
    public void draw(Batch batch, float parentAlpha) {
        Color color = getColor();
        batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
        batch.draw(flipped ? front : back, calculateX(logic.column), calculateY(logic.row), getWidth(), getHeight());
    }