Libgdx 中无法对 TextButton 执行缩放动画
Unable to perform scaling animation on TextButton in Libgdx
我想使用 Tween Engine 在文本按钮上执行缩放动画。
我对精灵和字体使用了相同的代码及其各自的访问器。但仅对于 TextButton,代码不起作用。这是代码:
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);
}
以下是我的 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;
}
}
}
在渲染方法中:
game.batch.setProjectionMatrix(camera2.combined);
levelupButton.draw(game.batch, 1);
按钮是在屏幕上绘制的,但不是动画的。谁能告诉我我做错了什么?
添加:button.setTransform(true);
到您的初始化方法
此处有更多信息:Why Libgdx's Table does not accept scale action?(TextButton 扩展 Table)
不过,我建议使用舞台并查看 scene2D 动作。这与通用补间引擎的作用相同,但更易于用于 scene2D actors(就像您已经在使用的按钮)
更多信息在这里:https://github.com/libgdx/libgdx/wiki/Scene2d#actions
由于性能原因,大多数 scene.ui 元素的默认转换设置为 false,因此您需要使用任何容器或 table。
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
您可以在 TweenAccessor 中使用容器,然后应用动画。
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;
}
}
}
我想使用 Tween Engine 在文本按钮上执行缩放动画。 我对精灵和字体使用了相同的代码及其各自的访问器。但仅对于 TextButton,代码不起作用。这是代码:
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);
}
以下是我的 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;
}
}
}
在渲染方法中:
game.batch.setProjectionMatrix(camera2.combined);
levelupButton.draw(game.batch, 1);
按钮是在屏幕上绘制的,但不是动画的。谁能告诉我我做错了什么?
添加:button.setTransform(true);
到您的初始化方法
此处有更多信息:Why Libgdx's Table does not accept scale action?(TextButton 扩展 Table)
不过,我建议使用舞台并查看 scene2D 动作。这与通用补间引擎的作用相同,但更易于用于 scene2D actors(就像您已经在使用的按钮)
更多信息在这里:https://github.com/libgdx/libgdx/wiki/Scene2d#actions
由于性能原因,大多数 scene.ui 元素的默认转换设置为 false,因此您需要使用任何容器或 table。
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
您可以在 TweenAccessor 中使用容器,然后应用动画。
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;
}
}
}