Previous Cycle

Back to Exercise Overview

Cycle 7: Add player names, blinking for the current player

It would be a nice feature to display the player's name close to the card hand. To further improve the user interface, the name of the player who makes the next draw could be blinking. Because the player names are defined dynamically when the players enter the game room, the blinking text is created as an instance of the class TextActor. Blinking can be obtained by showing and hiding the sprite image periodically using the act() method. To realize this idea we declare an additional class BlinkingName as follows:

// BlinkingName.java

import ch.aplu.jgamegrid.*;
import java.awt.*;

public class BlinkingName extends TextActor
{
  private boolean isBlinkingEnabled = false;

  public BlinkingName(String name)
  {
    super(true, name, Color.white,
     new Color(2552552550)new Font("Arial"Font.PLAIN, 16));
    setSlowDown(20);
 }

  public void act()
  {
    if (!isBlinkingEnabled)
    {
      if (!isVisible())
        show();
      return;
    }
    if (isVisible())
      hide();
    else
      show();
  }

  public void setBlinkingEnabled(boolean enable)
  {
    isBlinkingEnabled = enable;
  }
}

The blinking names for each players are stored in the CardGame class as an array instance variable:

private BlinkingName[] blinkingNames = new BlinkingName[nbPlayers];

and initialized in the CardTable constructor:

for (int i = 0; i < playerNames.length; i++)
  blinkingNames[i] = new BlinkingName(playerNames[i]);

We declares in a array instance variable where to show the text:

private final Location[] nameLocations =
{
  new Location(300, 440),
  new Location(150, 300),
  new Location(300, 160),
  new Location(450, 300)
};

and add the text actors to the game grid in initHands():

addActor(blinkingNames[toPlayerId(i)], textLocations[i]);

We may even align the text properly:

if (== 0 || i == 2)  // Center align text
  blinkingNames[toPlayerId(i)].setLocationOffset(
    new Point(-blinkingNames[toPlayerId(i)].getTextWidth() / 20));
if (== 3)  // Right align text
  blinkingNames[toPlayerId(i)].setLocationOffset(
    new Point(-blinkingNames[toPlayerId(i)].getTextWidth(), 0));

To enable/disable blinking we define the method setBlinking(int playerId) in the CardTable class. If playerId is negative, all names are non-blinking.

protected void setBlinking(int playerId)
{
  for (int i = 0; i < nbPlayers; i++)
    blinkingNames[i].setBlinkingEnabled(false);
  if (playerId > -1)
    blinkingNames[playerId].setBlinkingEnabled(true);
}

We invoke this method at several occasions: First whenever the player dropped out (using playerId = - 1), then in setMyTurn() using myPlayerId. Finally in setOtherTurn(), but here we need the information of the current player's id. It your work to implement the code to get this information from the server.

Proposal: On the server side you include the current player id as command parameter in the OTHER_TURN command and fetch it as data[1] in the Command.OTHER_TURN case of the Player's dataReceived() callback. Then you pass the id via a parameter to the setOtherTurn() method.

Execute the solution you should obtain (with 4 players).
If you are completely despaired, download the source code of the solution from here.

Previous Cycle
Back to Exercise Overview