Battle Balloons Week 5

Collision Detection

Willie Wheeler
Aug 25, 2017 · 3 min read
Crash! With collision detection, it’s time to be careful!

Welcome to week 5 of the Battle Balloons kids’ programming course. Please see the Battle Balloons Github repository for the game code. (Check out branch course/week05 if you want to follow along in the code.)

Last week we added obstacles to the game, but they didn’t do anything other than appear on the screen. This time around we’re going to make it where if you crash into them, you lose a life. This is called collision detection.

Check a single obstacle for a player collision

Implementing basic collision detection is pretty easy. We just want to see whether the player is overlapping with an obstacle. We already know that we’re going to have to have collision detection for other things too, so let’s add a collision detection method to our AbstractEntity class.

protected boolean collision(Entity that) {
int thisXLo = getX();
int thisXHi = thisXLo + getWidth();
int thisYLo = getY();
int thisYHi = thisYLo + getHeight();

int thatXLo = that.getX();
int thatXHi = thatXLo + that.getWidth();
int thatYLo = that.getY();
int thatYHi = thatYLo + that.getHeight();

boolean xOverlap = (thisXLo <= thatXHi) && (thisXHi >= thatXLo);
boolean yOverlap = (thisYLo <= thatYHi) && (thisYHi >= thatYLo);

return xOverlap && yOverlap;
}

In the code above, we are comparing two entities: “this” and “that”. Think of “this” being the player and “that” being an obstacle. The player and obstacle overlap if and only if their x spans overlap and their y spans overlap. See the screenshot above to see how it works.

Check all obstacles for player collisions

Next we need to update the GameModel class to check for collisions at each game tick. If there is a collision, then for now it’s game over.

package bb.model;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class GameModel {
private static final int INIT_NUM_OBSTACLES = 15;

private final Player player;
private final List<Obstacle> obstacles = new LinkedList<>();
private boolean gameRunning;

public GameModel() {
this.player = new Player(this);
for (int i = 0; i < INIT_NUM_OBSTACLES; i++) {
obstacles.add(new Obstacle(this));
}
this.gameRunning = true;
}

public Player getPlayer() {
return player;
}

public List<Obstacle> getObstacles() {
return obstacles;
}

public void update() {
if (gameRunning) {
updateEntities();
boolean collision = checkCollisions();
if (collision) {
this.gameRunning = false;
}
}
}

private void updateEntities() {
player.update();
obstacles.forEach(obstacle -> obstacle.update());
}

private boolean checkCollisions() {
for (ListIterator<Obstacle> it = obstacles.listIterator();
it.hasNext();) {
Obstacle obstacle = it.next();
if (player.collision(obstacle)) {
return true;
}
}
return false;
}
}

In the code above, we add a gameRunning variable to indicate whether the game is — you guessed it — still running. (See how good variable names make it easier to understand what’s going on?)

Then, in our update() method, we do the actual check to see whether the game is running. If not, then we don’t do anything because the game is over. Otherwise, we update all of the entities and then check for collisions, and if there’s a collision, then we set gameRunning to be false (game over).

In the checkCollisions() method, we iterate over the list of obstacles, and for each one we check whether the player collides with it. If there’s a collision, then the whole checkCollisions() method returns true. Otherwise, we return false.

That’s it! If you want to have some fun, though, keep reading.

Some fun things to try

  • Try changing the number of obstacles. (Hint: check out GameModel.)
  • Try changing the size of the obstacles. (Hint: see Obstacle.)
  • Try changing the obstacles into rectangles.
  • Try making the obstacle slide to the right. (Hint: you will need to add some code to the Obstacle.update() method. And since Obstacle extends the AbstractEntity class, take a look at the AbstractEntity methods and see if there’s anything there you can use.)
  • Try making new obstacles appear as the game progresses. (Hint: Look at how we create new Obstacles in the GameModel constructor. Can you do something similar in the GameModel.update() method?
  • After you make new obstacles appear, see if you can make them appear only occasionally. (Hint: Can you use a java.util.Random to help?)
  • See if you can make Lexi gain points for surviving the moving obstacles. (Hint: do something in the Player.update() method.)

Battle Balloons Lessons

Programming for Kids

Coding fun for kids and other new learners.

)

Willie Wheeler

Written by

Interested in applying machine learning and data science to problems in operations.

Programming for Kids

Coding fun for kids and other new learners.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade