Writing Games with Processing: Eating Platty

20. December, 2013

If you try the code from the last session, you’ll notice that the crocodiles can reach Platty but the game doesn’t end. We’re missing collision detection.

Following our KISS mantra, the collision detection should return true if a crocodile is “next” to a certain tile position (i.e. the distance in both x and y must be <= 1).

Add a new method to the class Enemy:

  boolean closeTo(int tx, int ty) {
    int dx = abs(x - tx);
    int dy = abs(y - ty);
    return dx <= 1 && dy <= 1;
  }

Next, we need to loop over all enemies and stop when one of them is close to Platty:

void checkCollisions() {
  for(Enemy e: enemies) {
    if(e.closeTo(px, py)) {
      gameOver(e);
      return;
    }
  }
}

Let’s add a fancy “Game Over” method:

void gameOver(Enemy e) {
  draw();
  noLoop();
  
  textAlign(CENTER, TOP);
  textSize(40);
  color outline = color(255,255,255);
  color fill = color(255,0,0);
  textWithOutline("GAME OVER", width/2, 200, outline, fill);
  
  textSize(20);
  textWithOutline("The poor platypus was eaten by "+e.name+"!", width/2, 240, outline, fill);
}

void textWithOutline(String message, int x, int y, color outline, color fill) {
  fill(outline);
  text(message, x-1, y);
  text(message, x+1, y);
  text(message, x, y-1);
  text(message, x, y+1);
  
  fill(fill);
  text(message, x, y);
}

Let’s test this game (I’m just pressing space to “wait”):

Broken Collision Detection
(Click the image to start the animation)

Hm… that’s not right. Benny should eat Platty one step earlier.

Let’s debug what is going on:

  boolean closeTo(int tx, int ty) {
    int dx = abs(x - tx);
    int dy = abs(y - ty);
    println(name+" dx="+dx+" dy="+dy);
    return dx <= 1 && dy <= 1;
  }

Output:

Kenny dx=14 dy=10
Benny dx=13 dy=10
Kenny dx=13 dy=9
Benny dx=12 dy=9

Notice how the enemy name makes debugging much easier.

Ah, distance is not in tiles, it’s in pixels. Let’s fix that:

  boolean closeTo(int tx, int ty) {
    int dx = abs(x - tx) / tileSize;
    int dy = abs(y - ty) / tileSize;
    //println(name+" dx="+dx+" dy="+dy);
    return dx <= 1 && dy <= 1;
  }

Corrected Game Over

Much better. And don’t forget to disable the debug output!

You can find the whole source code here.

Now that we have a way to lose the game, we should add a way to win.

Previous: Hunting Platty
First post: Getting Started