Exam Solution all the way to Part (f)

This is the version of the bouncers where they get swallowed by the obstacles rather than bouncing.

Implementation

final float DELTA_T = 1.0;

class Obstacle {
  PVector location;
  float length;

  Obstacle(PVector location_, float length_) {
    location = location_.copy();
    length = length_;
  }

  void display() {
    rectMode(CENTER);
    fill(0);
    rect(location.x, location.y, length, length);
  }
}

class Bouncer {
  PVector location;
  PVector velocity;
  float radius;
  boolean consumed;

  Bouncer(PVector location_, PVector velocity_, float radius_) {
    location = location_.copy();
    velocity = velocity_.copy();
    radius = radius_;
    consumed = false;
  }

  void update() {
    location.add(velocity.copy().mult(DELTA_T));
  }

  void display() {
    if (!consumed) {
      ellipseMode(CENTER);
      noFill();
      stroke(0);
      ellipse(location.x, location.y, 2 * radius, 2 * radius);
    }
  }

  void checkEdges() {
    if (location.x < radius) {
      location.x = radius;
      velocity.x *= -1;
    }
    if (location.x > width - radius) {
      location.x = width - radius;
      velocity.x *= -1;
    }
    if (location.y < radius) {
      location.y = radius;
      velocity.y *= -1;
    }
    if (location.y > height - radius) {
      location.y = height - radius;
      velocity.y *= -1;
    }
  }

  void bounce(Obstacle obstacle) {
    PVector obstacleLocation = obstacle.location;
    float obstacleLength = obstacle.length;
    if (location.x + radius > obstacleLocation.x - obstacleLength / 2 &&
      location.x - radius < obstacleLocation.x + obstacleLength / 2 &&
      location.y + radius > obstacleLocation.y - obstacleLength / 2 &&
      location.y - radius < obstacleLocation.y + obstacleLength / 2) {
      consumed = true;
    }
  }
}

Obstacle[] obstacles = new Obstacle[5];
Bouncer[] bouncers = new Bouncer[50];

void setup() {
  size(800, 600);
  for (int i = 0; i < obstacles.length; ++i) {
    obstacles[i] = new Obstacle(new PVector(random(0, width), random(0, height)), random(25, 50));
  }
  for (int i = 0; i < bouncers.length; ++i) {
    bouncers[i] = new Bouncer(new PVector(random(0, width), random(0, height)), new PVector(random(-20, 20), random(-20, 20)), random(5, 10));
  }
}

void draw() {
  background(255);
  for (int i = 0; i < obstacles.length; ++i) {
    obstacles[i].display();
  }
  for (int j = 0; j < bouncers.length; ++j) {
    bouncers[j].update();
    for (int i = 0; i < obstacles.length; ++i) {
      bouncers[j].bounce(obstacles[i]);
    }
    bouncers[j].checkEdges();
    bouncers[j].display();
  }
}