Problem With Collision

Anyway. Collisions. Since the thing that we really care about colliding with is enemies, let’s loop over every enemy. if we collide that enemy with the player, the player dies.

Then let’s loop over all the bullets. If that enemy collides with that bullet, both that enemy and that bullet die.

… What does it mean for an object to die? Well, we can add an alive boolean to each of our objects. And then only draw them if they are alive. And of course only alive things can cause collisions.

class Player {
  int which_image;
  float position_x;
  float position_y;
  float size_w;
  float size_h;
  boolean alive;
  Player(float start_position_x, float start_position_y) {
    which_image = 0;
    position_x = start_position_x;
    position_y = start_position_y;
    size_w = images[which_image].width;
    size_h = images[which_image].height;
    alive = true;
  }
  void draw() {
    if (alive) {
      move();
      image( images[which_image], position_x, position_y );
    }
  }
  void move() {
    position_x = mouseX;
    position_y = mouseY;
  }
  void die() {
    alive = false;
  }
}

class Foe {
  int which_image;
  float position_x;
  float position_y;
  float size_w;
  float size_h;
  boolean alive;
  Foe(float start_position_x, float start_position_y) {
    which_image = 2;
    position_x = start_position_x;
    position_y = start_position_y;
    size_w = images[which_image].width;
    size_h = images[which_image].height;
    alive = true;
  }
  void draw() {
    if (alive) {
      move();
      image( images[which_image], position_x, position_y );
    }
  }
  void move() {
    position_x += 0;
    position_y += 3;
    if ( position_y > height ) {
      position_y = -size_h;
    }
  }
  void die() {
    alive = false;
  }
  boolean collides(float ox, float oy, float ow, float oh) {
    return((ox + ow >= position_x && ox <= position_x + size_w && oy + oh >= position_y && oy <= position_y + size_h));
  }
}

class Bullet {
  int which_image;
  float position_x;
  float position_y;
  float size_w;
  float size_h;
  boolean alive;
  Bullet(float start_position_x, float start_position_y) {
    which_image = 1;
    position_x = start_position_x;
    position_y = start_position_y;
    size_w = images[which_image].width;
    size_h = images[which_image].height;
    alive = true;
  }
  boolean draw() {
    if (alive) {
      move();
      image(images[which_image], position_x, position_y );
    }
    return(!alive || position_y < -size_h);
  }
  void move() {
    position_x += 0;
    position_y -= 3;
  }
  void die() {
    alive = false;
  }
}

PImage[] images;

Player player;
Foe[] foes;
ArrayList<Bullet> bullets;

void setup() {
  size(800, 600);
  // Load the images. Or spoof them.
  images = new PImage[5];
  background(255, 0, 0);
  images[0] = get(0, 0, 20, 20);//loadImage ("Steven.png");
  background(255, 255, 0);
  images[1] = get(0, 0, 20, 20);//loadImage ("tiro.png");
  background(0, 255, 0);
  images[2] = get(0, 0, 20, 20);//loadImage ("Rubi.png");
  // Create the Player.
  player = new Player(width/2, height/2);
  // Create the Foes.
  foes = new Foe[5];
  for ( int i = 0; i < foes.length; i++) {
    foes[i] = new Foe( 50 + 100 * i, 0 );
  }
  // Create the bullets.
  bullets = new ArrayList();
}

void draw() {
  background(0, 120, 240);
  noStroke();
  fill(127);
  rect(550, 0, 250, height);
  // Draw the player.
  player.draw();
  // Draw the Foes.
  for (int i = 0; i < foes.length; foes[i++].draw());
  // Draw the Bullets.
  for (int i = bullets.size()-1; i >=0; i--) if (bullets.get(i).draw()) bullets.remove(i);

  // Collisions!
  for (int i = 0; i < foes.length; i++) {
    // Is this foe alive and does this foe collide with the player?
    if (foes[i].alive && foes[i].collides(player.position_x, player.position_y, player.size_w, player.size_h)) {
      // Kill the player. This is the sort of comment you can leave out. I mean, player.die() is pretty clear, right?
      player.die();
    }
    for (int j = bullets.size()-1; j >= 0; j--) {
      // Are an alive foe and an alive bullet colliding?
      if( foes[i].alive && bullets.get(j).alive && foes[i].collides(bullets.get(j).position_x, bullets.get(j).position_y, bullets.get(j).size_w, bullets.get(j).size_h)) {
        // Kill this bullet and that foe.
        bullets.get(j).die();
        foes[i].die();
      }
    }
  }
}

void mousePressed() {
  // Add a new bullet if the player is alive.
  if(player.alive){
    bullets.add( new Bullet(mouseX, mouseY) );
  }
}

And that works. It works great. But it’s still a mess.