Enhancing the game screen's GUI

The last part of this chapter is dedicated to two enhancements of the game screen's GUI. Firstly, we will add a small animation that gives visual feedback to the player when a life is lost. Secondly, a counting-up animation for the player's score will be implemented.

Event – player lost a life

We want to play a small animation in the event when the player has just lost a life. The extra lives are shown as bunny heads in the top-right corner of the game screen. These icons become dark one after another as soon as another life has been lost. The animation we are aiming for is a temporary bunny head icon on top of the just lost extra life. The temporary icon is going to be scaled up, rotated, and will have a slightly red tint.

The following screenshot is an example of the animation:

Event – player lost a life

Add the following line to the WorldController class:

public float livesVisual;

After this, make the following changes to the same class:

private void init () {
Gdx.input.setInputProcessor(this);
cameraHelper = new CameraHelper();
lives = Constants.LIVES_START;
livesVisual = lives;
timeLeftGameOverDelay = 0;
initLevel();
}

public void update (float deltaTime) {
handleDebugInput(deltaTime);
if (isGameOver()) {
timeLeftGameOverDelay -= deltaTime;
if (timeLeftGameOverDelay< 0) backToMenu();
  } else {
handleInputGame(deltaTime);
  }
level.update(deltaTime);
testCollisions();
cameraHelper.update(deltaTime);
if (!isGameOver() &&isPlayerInWater()) {
lives--;
if (isGameOver())
timeLeftGameOverDelay = Constants.TIME_DELAY_GAME_OVER;
else
initLevel();
  }
level.mountains.updateScrollPosition(cameraHelper.getPosition());
if (livesVisual> lives)
livesVisual = Math.max(lives, livesVisual - 1 * deltaTime);
}

We have introduced a new variable livesVisual that will contain pretty much the same information as lives. However, livesVisual will only decrease slowly over time whenever the lives are decreased. This enables us to play an animation as long as livesVisual has not yet reached the current value of lives.

Additionally, add the following import line to the WorldRenderer class:

import com.badlogic.gdx.math.MathUtils;

Next, make the following changes to the same class:

private void renderGuiExtraLive (SpriteBatch batch) {
float x = cameraGUI.viewportWidth – 50 Constants.LIVES_START * 50;
float y = -15;
for (int i = 0; i<Constants.LIVES_START; i++) {
if (worldController.lives<= i)
batch.setColor(0.5f, 0.5f, 0.5f, 0.5f);
batch.draw(Assets.instance.bunny.head, x + i * 50, y, 50, 50, 120, 100, 0.35f, -0.35f, 0);
batch.setColor(1, 1, 1, 1);
}
if (worldController.lives>= 0 &&worldController.livesVisual>worldController.lives) {
int i = worldController.lives;
float alphaColor = Math.max(0, worldController.livesVisual - worldController.lives - 0.5f);
float alphaScale = 0.35f * (2 + worldController.lives - worldController.livesVisual) * 2;
float alphaRotate = -45 * alphaColor;
batch.setColor(1.0f, 0.7f, 0.7f, alphaColor);
batch.draw(Assets.instance.bunny.head, x + i * 50, y, 50, 50, 120, 100, alphaScale, -alphaScale, alphaRotate);
batch.setColor(1, 1, 1, 1);
  }
}

The added code will draw a temporary bunny head icon that is changed in its alpha color, scale, and rotation over time to create the animation. The progress of the animation is controlled by the current value in livesVisual.

Event – score increased

Every time the player collects an item, a reward is given that is added to the overall game score. The current score and a gold coin icon are shown in the top-left corner of the game screen. We want to add two subtle effects that begin to play when an increased score is detected. Firstly, we want the score to slowly add up to the new score. Secondly, the gold coin icon will shake a bit while the score is still adding up.

Here is a screenshot of the combined animation in five steps where some items have been collected:

Event – score increased

Add the following line to the WorldController class:

public float scoreVisual;

Next, make the following changes to the same class:

private void initLevel () {
score = 0;
scoreVisual = score;
level = new Level(Constants.LEVEL_01);
cameraHelper.setTarget(level.bunnyHead);
}  
public void update (float deltaTime) {
  ...
level.mountains.updateScrollPosition(cameraHelper.getPosition());
if (livesVisual> lives)
livesVisual = Math.max(lives, livesVisual - 1 * deltaTime);
if (scoreVisual< score)
scoreVisual = Math.min(score, scoreVisual + 250 * deltaTime);
}

We introduced the new variable scoreVisual, which serves the same purpose as livesVisual does to control the progress of the score animation.

Additionally, make the following changes to the WorldRenderer class:

private void renderGuiScore (SpriteBatch batch) {
float x = -15;
float y = -15;
float offsetX = 50;
float offsetY = 50;
if (worldController.scoreVisual<worldController.score) {
long shakeAlpha = System.currentTimeMillis() % 360;
float shakeDist = 1.5f;
offsetX += MathUtils.sinDeg(shakeAlpha * 2.2f) * shakeDist;
offsetY += MathUtils.sinDeg(shakeAlpha * 2.9f) * shakeDist;
  }
batch.draw(Assets.instance.goldCoin.goldCoin, x, y, offsetX, offsetY, 100, 100, 0.35f, -0.35f, 0);
Assets.instance.fonts.defaultBig.draw(batch, "" + (int)worldController.scoreVisual, x + 75, y + 37);
}

The value in scoreVisual is cast to an integer value to cut off the fraction. The resulting intermediate value will be the score that is shown in the GUI for the counting-up animation. To let the coin icon shake, we use a sine function with different factors as input angles to find the offset for the temporary displacement of the icon.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.229.111