Interpolation between numbers - Libgdx

I’m trying to implement a simple “counting numbers” animation in my game. I want that whenever the score is changed, the numbers will start to count up/down until they have reached the desired number.

I tried to implement this by doing this:

points = new Label(""+ScoreManager.getPlayerScore(), skin, "default-nice") {
			private float target, rendered;
			public void act(float delta) {
				super.act(delta);
				target = ScoreManager.getPlayerScore();
                rendered = rendered < target ? Interpolation.linear.apply(rendered, target, 0.05f) : Interpolation.linear.apply(target, rendered, 0.05f);
                setText("" + MathUtils.ceil(target));
			}
		};

But it has no affect. The numbers are still changed suddently.

P.S I have one more question, not related to this topic - How can I define a fixed position to a table? I set a position for a table in my game but it can changed according to its children’s width and height.

You can only set the absolute positions of tables of they are added to the parent without a cell.

So rather than add(), use addActor(). For nice little animations, check out scene2d actions and the Interpolation class.

The Interpolation alpha parameter is from 0 to 1. For your situation, use x/y where x is the amount of time since the score changed and y is how long the you want the visual score change to take.

I’m sorry but I didn’t quite understand what you said. Could you please elaborate about that?


float time = 0;
float duration = 3;
int lastScore = 123;
int actualScore = 456;
while (time < duration) {
	float alpha = Math.min(1, time / duration);
	int visualScore = (int)Interpolation.pow2Out.apply(lastScore, actualScore, alpha);
	System.out.println(visualScore);
	time += 0.032;
}

Once you understand that, apply it to your game. Set time=0 when the score changes, increment time each frame. Pro tip: when score changes, clear actions, then add a TemporalAction that adjusts the visual score.

Thanks for your help. I tried what you said but I keep failing to get it to work properly. Here is my code:

points = new Label("0", skin, "default-nice") {
			private final float duration = 3;
			private float time = 0, alpha;
			private int lastScore, actualScore, visualScore;
			public void act(float delta) {
				super.act(delta);
				lastScore = Integer.parseInt(points.getText().toString());
				actualScore = hudManager.getListener().getPlayerScore();
				if(time<duration) {
					alpha = Math.min(1, time / duration);
					visualScore = (int)Interpolation.pow2Out.apply(lastScore, actualScore, alpha);
					setText(""+visualScore);
					time += 0.010;
				} else {
					lastScore = actualScore;
				}
			}
		};

Right now whenever the player score changes, the visual score remains “0”.

Edit: Nevermind, I got it! Thanks for your help, Nate! Here is my new-working code:

points = new Label("0", skin, "default-nice") {
			private final float duration = 0.5f;
			private float time = 0, alpha;
			private int lastScore = 0, actualScore, visualScore;
			public void act(float delta) {
				super.act(delta);
				actualScore = hudManager.getListener().getPlayerScore();
				if(actualScore != lastScore) {
					if(time<duration) {
						alpha = Math.min(1, time / duration);
						visualScore = (int)Interpolation.pow2Out.apply(lastScore, actualScore, alpha);
						setText(""+visualScore);
						time += 0.010;
					} else {
						lastScore = actualScore;
						time = 0;
					}
				}
			}
		};

Great! Though “time += 0.010;” should be “time += delta;”.