5

I've asked a question like 4 days ago. Got some help and now my code looks like

ColorAction actionBtG = new ColorAction();
ColorAction actionGtB = new ColorAction();
SequenceAction sequenceAction;
RepeatAction repeatAction = new RepeatAction();
ShapeRenderer shapeRenderer;
Color blue = new Color(Color.BLUE);

@Override
public void create () {

    shapeRenderer = new ShapeRenderer();
    actionBtG.setColor(blue);
    actionBtG.setEndColor(Color.GOLD);
    actionBtG.setDuration(5);

    actionGtB.setColor(blue);
    actionGtB.setEndColor(Color.BLUE);
    actionGtB.setDuration(5);
    sequenceAction = new sequenceAction(actionBtG,actionGtB);






    repeatAction = new RepeatAction():        
    repeatAction.setAction(sequenceAction);
    repeatAction.setCount(RepeatAction.FOREVER);
}

@Override
public void render () {

    repeatAction.act(Gdx.graphics.getDeltaTime());
    Gdx.gl.glClearColor(1,1,1,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
    shapeRenderer.setColor(blue);
    shapeRenderer.rect(100, 100, 40, 40);
    shapeRenderer.end();


}

But it still works wrong. It does action once and stops. When I need to loop that. From blue to gold, then from gold to blue. I would really appreciate any help, because I'm just learning libGDX. Thanks.

I have read all of the answers and edited my code, but it still doesnt work:

private Actor actionManager = new Actor();
ColorAction actionBtG = new ColorAction();
ColorAction actionGtB = new ColorAction();
SequenceAction sequenceAction;
RepeatAction repeatAction;
Color activeColor = new Color(Color.BLUE);
ShapeRenderer shapeRenderer;


@Override
public void create () {

    shapeRenderer = new ShapeRenderer();
    actionBtG.setColor(activeColor);
    actionBtG.setEndColor(Color.GOLD);
    actionBtG.setDuration(5);

    actionGtB.setColor(activeColor);
    actionGtB.setEndColor(Color.BLUE);
    actionGtB.setDuration(5);
    sequenceAction = new SequenceAction(actionBtG,actionGtB);
    repeatAction = new RepeatAction();
    repeatAction.setAction(sequenceAction);
    repeatAction.setCount(RepeatAction.FOREVER);

    actionManager.addAction(repeatAction);
}

Here is render()

@Override
    public void render () {
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    actionManager.act(Gdx.graphics.getDeltaTime());

    shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
    shapeRenderer.setColor(blue);
    shapeRenderer.rect(100, 100, 40, 40);
    shapeRenderer.end();
}

Now it's not changing the color, it's always blue.

Gtzzy
  • 519
  • 4
  • 18
  • 1
    Where do you [set the target](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/Action.html#setTarget-com.badlogic.gdx.scenes.scene2d.Actor-) of the `Action`? – asherbret Jan 07 '16 at 09:33
  • @user2016436 ColorActions don't need a target if you use `setColor` on them. – Tenfour04 Jan 07 '16 at 16:46
  • It would be a good idea to rename `blue` to something else, since you don't intend for it to stay blue. – Tenfour04 Jan 07 '16 at 17:30
  • Did you forget to update the name of the color in `shapeRenderer.setColor` or is that just a typo in the code you pasted above? I don't see any other errors. – Tenfour04 Jan 07 '16 at 20:29
  • In my project - it's fine, i've just copypasted the above code twice and edited it here. – Gtzzy Jan 07 '16 at 20:31

3 Answers3

3

You're encountering a bug related to Actions expecting to be used with Actors. A lot of Actions work fine without an Actor, but SequenceAction does not because it expects to be attached to an Actor to detect if it should still be running.

So a somewhat hacky solution would be to add a dummy actor to your top level action when you set it up. This simulates what happens when you add an action to an actor in a stage.

repeatAction.setActor(new Actor());

If you plan to use more Actions in your app, you can create a single Actor that you use to manage all your actions:

private Actor actionManager = new Actor();

//when creating actions:
actionManager.addAction(repeatAction);

//In render(), use this instead of calling act on individual actions
//It will call act on all actions in the actor:
actionManager.act(Gdx.graphics.getDeltaTime());

And of course, if you want to use a Stage for drawing stuff, you could simply add your actions to the Stage instead of using an Actor as your action manager.

I personally find scene2d Actions must easier to use and set up than UniversalTweenEngine.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • I also think libgdx actions are easier to set up than Universal Tween Engine however if your game objects are not all libgdx actors what other choice do you have? Eventually you'll probably want to tween something that can't be tweened with libgdx actions. For a big project it seems inevitable that you will want to use Universal Tween Engine. – Barodapride Jan 07 '16 at 19:53
  • @Tenfour04 did like u said in the second half of ur answer, added some info to the question. – Gtzzy Jan 07 '16 at 19:57
  • It works, dont know how, but it works. I've just created a new project and write the whole code manually w/o copypasting. Thanks everybody. – Gtzzy Jan 07 '16 at 22:54
2

So the following sample worked for me (infinite rotation)

Method 1: (recommended)

loadingActor.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.rotateBy(360, 1)));

Method 2:

Image loadingActor = new Image(AssetsController.getInstance().getLoading());
loadingActor.setOrigin(Align.center);
final SequenceAction infiniteRotate = Actions.sequence();
infiniteRotate.addAction(Actions.rotateTo(0 , 0f) );
infiniteRotate.addAction(Actions.rotateTo(360 , 1f) );
loadingActor.addAction(Actions.forever(infiniteRotate));
ultra.deep
  • 1,699
  • 1
  • 19
  • 23
0

Libgdx Actions are only for Libgdx Actors. You're creating an action but not assigning it to an Actor. You're just setting the shapeRenderer color to blue, disregarding the action you created. I would recommend using a tween from Universal tween engine if you want to change the color over time.

Alternatively, you could ditch the shapeRenderer and use an Image (subclass of Actor). You'd then assign your action to the Image. But to do that, you'd have to create a stage and add your Image to the stage. See the scene2d wiki.

Either way is going to be a few extra steps. Perhaps a cheap hack to get this working easily would be:

  1. just create an Image:

    Image i = new Image();

  2. assign your action to the image i

    i.addAction(repeatAction);

  3. replace repeatAction.act(...) with

    i.act(Gdx.graphics.getDeltaTime());

  4. change shapeRenderer.setColor(blue) to

    shapeRenderer.setColor(i.getColor());

Hope that helps.

Barodapride
  • 3,475
  • 4
  • 25
  • 36
  • 1
    Actually, since the color actions are targeting the `blue` Color instance, the shape renderer is indeed reading the correct changing color value out of the actions. – Tenfour04 Jan 07 '16 at 17:29
  • I see, what's more interesting to me is that you can have actions not associated to actors. That seems really useful. I didn't know that. Now I'm going to use runnable delayed actions all over the place. – Barodapride Jan 07 '16 at 18:37
  • I think it's particular to ColorAction. See my other answer. You can use a dummy actor as your action manager. – Tenfour04 Jan 07 '16 at 18:53