0

I want to perform scale animation on a text button using Tween Engine. I have used the same code for sprites and fonts with their respective Accessors. But for only TextButton, code is not working. Here is the code :

private void initLevelUpAnimation() {


    Log.d("Runnable", "animation method called");

    Skin skin = new Skin(); //empty constructor causes it not to load yet.
    skin.add("level_new", levelUpBG);

    levelupButtonStyle = new TextButton.TextButtonStyle();
    levelupButtonStyle.font = game.levelUpFont;
    levelupButtonStyle.up = skin.getDrawable("level_new");
    levelupButtonStyle.down = skin.getDrawable("level_new");
    levelupButtonStyle.over = skin.getDrawable("level_new");
    levelupButtonStyle.disabled = skin.getDrawable("level_new");


    levelupButton = new TextButton("LEVEL " + (baseLevel + 1) + "\n" + "KEEP GOING", levelupButtonStyle);
    levelupButton.setSize(265, 180);
    levelupButton.setPosition(gamePlayBG.getWidth() / 2 - levelupButton.getWidth() / 2,
            gamePlayBG.getHeight() / 2 - levelupButton.getHeight() / 2);

    Log.d("TWEEN", "Read to animate: ");

    Tween.to(levelupButton, ButtonAccessor.SCALE_XY, 0.01f)
            .ease(Elastic.INOUT)
            .target(0.1f, 0.1f)
            .setCallback(new TweenCallback() {
                @Override
                public void onEvent(int type, BaseTween<?> source) {
                    stopGameObjects = true;
                    Log.d("TWEEN", "First completed : 0.3");
                    Tween.to(levelupButton, ButtonAccessor.SCALE_XY, 0.7f)
                            .ease(Elastic.INOUT)
                            .target(1.1f, 1.1f)
                            .setCallback(new TweenCallback() {
                                @Override
                                public void onEvent(int type, BaseTween<?> source) {
                                    Log.d("TWEEN", "Second completed : 0.3");
                                    Tween.to(levelupButton, ButtonAccessor.SCALE_XY, 0.7f)
                                            .ease(Elastic.INOUT)
                                            .target(0.8f, 0.8f)
                                            .setCallback(new TweenCallback() {
                                                @Override
                                                public void onEvent(int type, BaseTween<?> source) {
                                                    Log.d("TWEEN", "Third completed : 0.3");

                                                    Tween.to(levelupButton, ButtonAccessor.SCALE_XY, 1.0f)
                                                            .ease(Elastic.OUT)
                                                            .target(1.3f, 1.3f)
                                                            .setCallback(new TweenCallback() {
                                                                @Override
                                                                public void onEvent(int type, BaseTween<?> source) {

                                                                    Log.d("TWEEN", "Fourth completed : 0.7");


                                                                    Tween.to(levelupButton, ButtonAccessor.ROTATION, 1.0f)
                                                                            .ease(Elastic.OUT)
                                                                            .target(1.0f, 1.0f)
                                                                            .setCallback(new TweenCallback() {
                                                                                @Override
                                                                                public void onEvent(int type, BaseTween<?> source) {
                                                                                    Log.d("TWEEN", "Fifth completed : 1.0");


                                                                                    stopGameObjects = false;

                                                                                    updateScoreTime();
                                                                                }
                                                                            })
                                                                            .start(game.tweenManager);
                                                                }
                                                            })
                                                            .start(game.tweenManager);
                                                }
                                            })
                                            .start(game.tweenManager);
                                }
                            })
                            .start(game.tweenManager);
                }
            })
            .start(game.tweenManager);
 }

Following is my ButtonAccessor :

public class ButtonAccessor implements TweenAccessor<TextButton> {
public static final int ALPHA = 0;
public static final int POS_XY = 1;
public static final int CPOS_XY = 2;
public static final int SCALE_XY = 3;
public static final int ROTATION = 4;
public static final int OPACITY = 5;
public static final int TINT = 6;

@Override
public int getValues(TextButton target, int tweenType, float[] returnValues) {
    switch (tweenType) {
        case ALPHA:
            returnValues[0] = target.getColor().a;
            return 1;

        case SCALE_XY:
            returnValues[0] = target.getScaleX();
            returnValues[1] = target.getScaleY();
            return 2;

        case OPACITY:
            returnValues[0] = target.getColor().a;
            return 1;

        case TINT:
            returnValues[0] = target.getColor().r;
            returnValues[1] = target.getColor().g;
            returnValues[2] = target.getColor().b;
            return 3;

        default:
            assert false;
            return -1;
    }

}

@Override
public void setValues(TextButton target, int tweenType, float[] newValues) {
    switch (tweenType) {
        case ALPHA:
            target.setColor(target.getColor().r, target.getColor().g, target.getColor().b, newValues[0]);
            break;
        case SCALE_XY:
            target.setScale(newValues[0], newValues[1]);
            break;

        case OPACITY:
            Color c = target.getColor();
            c.set(c.r, c.g, c.b, newValues[0]);
            target.setColor(c);
            break;

        case TINT:
            c = target.getColor();
            c.set(newValues[0], newValues[1], newValues[2], c.a);
            target.setColor(c);
            break;

        default:
            assert false;
    }

}
}

In render method :

        game.batch.setProjectionMatrix(camera2.combined);

        levelupButton.draw(game.batch, 1);

Button is drawn in screen but not animated. Can anyone tell me what I am doing wrong here ?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Nir Patel
  • 357
  • 4
  • 17

2 Answers2

1

add: button.setTransform(true); to your init method

More info here: Why Libgdx's Table does not accept scale action? (a TextButton extends Table)

I would however recommend to use a stage and look into scene2D actions. This does the same as the universal tween engine but is simpler to use for scene2D actors (like the button you are already using)

More info here: https://github.com/libgdx/libgdx/wiki/Scene2d#actions

Community
  • 1
  • 1
p.streef
  • 3,652
  • 3
  • 26
  • 50
  • Well great, then you just wasted both our time! Please post all relevant code.. It might be that the .draw() method does not use the scale without the use of a stage. – p.streef Apr 20 '17 at 11:30
  • updated answer (untested). If this does not work, you need a stage – p.streef Apr 20 '17 at 11:37
  • button.setTransform(true); worked fine. But it performed scaling on the font only. Background was still. I need to make animation for whole button including background and font. Any suggetions on that ? – Nir Patel Apr 20 '17 at 11:43
0

By default transform on most scene.ui elements set as false due to performance reason so you need to use any container or table for the same.

TextButton button = new TextButton("Text Button", skin);
Container wrapper = new Container(button);
wrapper.setTransform(true);
wrapper.setOrigin(wrapper.getPrefWidth() / 2, wrapper.getPrefHeight() / 2);
wrapper.setRotation(45);
wrapper.setScaleX(1.5f);

https://github.com/libgdx/libgdx/wiki/Scene2d.ui#rotation-and-scale

You can user use Container in TweenAccessor and then apply animation.

public class ContainerAccessor implements TweenAccessor<Container> {

public static final int SCALE_XY = 3;

@Override
public int getValues(Container target, int tweenType, float[] returnValues) {
    switch (tweenType) {

        case SCALE_XY:
            returnValues[0] = target.getScaleX();
            returnValues[1] = target.getScaleY();
            return 2;

        default:
            assert false;
            return -1;
    }

}

@Override
public void setValues(Container target, int tweenType, float[] newValues) {
    switch (tweenType) {

        case SCALE_XY:
            target.setScale(newValues[0], newValues[1]);
            break;

        default:
            assert false;
    }

}
}
Abhishek Aryan
  • 19,936
  • 8
  • 46
  • 65
  • I tried downloading the class from https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/scenes/scene2d/ui/Container.java But a lot of things are missing for the version I am using for Libgdx. – Nir Patel Apr 20 '17 at 12:08
  • why don't you update your project to latest version of libgdx ? – Abhishek Aryan Apr 20 '17 at 12:10
  • If you rely on gradle then you can easily upgrade your project to latest version. – Abhishek Aryan Apr 20 '17 at 12:11
  • I tried updating .jar multiple times. But I keep getting this error : java.lang.NoClassDefFoundError: com.badlogic.gdx.backends.android.AndroidGL10 on this method "initializeForView" I have changed GL10 to GL20 throughout app. Still get the same error. – Nir Patel Apr 20 '17 at 12:38
  • updating .jar or .jars(libgdx having lot of jar) so instead of updating manually all jar just update version in root `build.gradle` file and refresh project, it automatically update to your project module with given verion. – Abhishek Aryan Apr 20 '17 at 12:41