Battle Balloons Week 3

Player Animation

This post covers the exercises and code written for week 3 of the Battle Balloons Java programming course.

Last week, we updated our player update method to be able to move the player around the arena with keyboard controls. We did this by changing the values of dx and dy depending on which key was pressed.

Right now, our player Lexi is just one image that moves in different directions. This week we’re going to make Lexi look like she’s walking in the directions that she’s moving. In other words, we are going to animate Lexi. To animate the player, we have to show a few images in sequence to make it look like the player is moving. We can accomplish this with a spritesheet. A spritesheet contains multiple images that we use to cycle through to animate. See src/main/resources/bb-sprites.png.

Before starting, make sure that you download the week03 zip file from the Battle Balloons code repository, open the project in Atom, and navigate to the project folder in your terminal.

Step 1. First, we need to give our player direction. We can start by creating a Direction enum. We have the file already created for us, so open the file src/main/java/bb/model/Direction.java. We need to define which directions we want to use here. When we move the player with the keyboard there are eight possible directions: UP, DOWN, LEFT, RIGHT, UP_LEFT, UP_RIGHT, DOWN_LEFT, and DOWN_RIGHT. Let’s add these to the Direction enum:

package bb.model;

public enum Direction {
UP,
DOWN,
LEFT,
RIGHT,
UP_LEFT,
UP_RIGHT,
DOWN_LEFT,
DOWN_RIGHT
}

Step 2. Now that we have a concept of direction to use, let’s give our Player a direction. Open the file src/main/java/bb/model/Player.java. Near the top of our player class, add the player direction by adding this line:

private Direction direction;

Then add an initial direction in our class constructor just after the TODO on line 27:

public Player() {
center();
// TODO: initialize player direction
this.direction = DOWN;
}

Step 3. Since we are animating our player, we need a number that will tell us which image on the spritesheet we need to use at any given time. Add an animation counter to the Player.java file just below where we gave the player the direction:

private Direction direction;
private int animationCounter;

So we can see the animationCounter running, let’s add a log statement to the function incrementAnimationCounter:

private void incrementAnimationCounter() {
this.animationCounter = (animationCounter + 1) % 4;
       // TODO: add log statement of animationCounter
log.trace("animationCounter={}", this.animationCounter);
}

Next, compile and start the game then watch the console output display the animationCounter. This number will help us pick which image to display on each value of the counter.

Notice when you change directions of the player, the sprite will not change direction. This is because we still have to specify which part of the spritesheet we want to use based on the direction of the player.

Step 4. Open the file src/main/java/bb/view/arena/SpriteUtil.java. The getCurrentSprite method will give us a set of images from the spritesheet based on the direction of the player. In the switch statement, the spriteBaseIndex is set for only the directions LEFT, UP_LEFT, DOWN_LEFT. Add the following, below the TODO on line 27, to add the remaining directions:

switch (direction) {
case LEFT:
case UP_LEFT:
case DOWN_LEFT:
spriteBaseIndex = 8;
break;
// TODO: Add remaining direction cases
case RIGHT:
case UP_RIGHT:
case DOWN_RIGHT:
spriteBaseIndex = 12;
break;
case UP:
spriteBaseIndex = 0;
break;
case DOWN:
spriteBaseIndex = 4;
break;

}

Save your file, compile, and watch the player change the image based on the direction. We have animated our character!

Changing the Sprite

Now that we have a working animation for our character, we can change which sprite we use for our character. There are two ways we can do this.

Method 1. With our current spritesheet, we have two rows of images that we can use for our player. Choose which row you want to use of that spritesheet by opening the file src/main/java/bb/view/SpriteFactory.java and change the row value in the method call of buildSpriteSheet on line 19. Change the value from 0 to 1 to select the second row in the spritesheet:

this.lexi = buildCharacterSprites(sheet, 1);

Method 2. You can specify your own sprite sheet to use by changing the value of SPRITE_SHEET_FILENAME on line 35 of src/main/java/BBConfig.java. Make sure your custom spritesheet is in the directory src/main/resources. You can use some of the other sheets in that directory as well like blue.png and arrow.png. Look to the next section to see how to create your own spritesheet.

Creating your own Sprite Sheet

In Battle Balloons, our sprite sheet has to follow a few rules.

  • Each sprite has to be 16x16 pixels.
  • The spritesheet has to be 12 images on a single row: 3 for the up animation, 3 for the down animation, 3 for the left animation, and 3 for the right animation.

To create a spritesheet, we’ll use www.piskelapp.com. Once you’ve created your first image click on Add new frame. Repeat this process until you’ve all 12 images or frames. Export the spritesheet by selecting the Export button on the right of the web page. Make sure the resolution is 16x16, the file type should be PNG. Under Spritesheet layout options, columns should be 12 and rows should be 1. Once the file has downloaded, copy the file from your download location to the project under src/main/java/resources. Then, change the value of SPRITE_SHEET_FILENAME as outlined in method 2 of the Changing your Sprite section above.

Battle Balloons Lessons