Table of ContentsInput HandlingGame Over

Collision Detection

Since you have both the vehicles and the wombat moving, the potential exists for the two to collide (rather a bad idea from the wombat's perspective). To get this going, you need to add code to determine when a collision occurs, and then react accordingly.

Collision detection can be a complex business. Thankfully, your requirements are relatively simple for RoadRun. The only potential collision is between the wombat and one of the vehicles. Life is also easier because of the limited number of objects with which the wombat can potentially collide. You can therefore implement collision detection by checking that the wombat's bounding rectangle is not intersecting any of the vehicles' rectangles. To do this, add some code to the Actor class.

/**
 * Simple collision detection checks if a given point is in the Actor's
 * bounding rectangle.
 * @param px The x position of the point to check against.
 * @param py The y position of the point to check against.
 * @return true if the point px, py is within this Actor's bounding rectangle
 */
public boolean isCollidingWith(int px, int py)
{
   if (px >= getX() && px <= (getX() + getActorWidth()) &&
       py >= getY() && py <= (getY() + getActorHeight()) )
      return true;
   return false;
}

/**
 * Determines if another Actor has collided with this one. We do this by
 * checking if any of the four points in the passed in Actor's bounding 
 * rectangle are within the bounds of this Actor's (using the isCollidingWith
 * point method above)
 * @param another The other Actor we're checking against.
 * @return true if the other Actor's bounding box collides with this one.
 */
public boolean isCollidingWith(Actor another)
{
   // check if any of our corners lie inside the other actors'
   // bounding rectangles
   if (isCollidingWith(another.getX(), another.getY()) ||
       isCollidingWith(another.getX() + another.getActorWidth(), another.getY()) ||
       isCollidingWith(another.getX(), another.getY() + another.getActorHeight()) ||
       isCollidingWith(another.getX() + another.getActorWidth(),
                       another.getY() + another.getActorHeight()))
      return true;
   else
      return false;
}

This code determines whether a collision occurs by checking whether any of one object's corners are within the bounding rectangle of another. You can see this concept illustrated in Figure 7.8. As a convenience I'm using two methods; one determines whether a collision occurs between the actor and another, and the other is a utility method to check whether the actor has collided with a single 2D point.

Figure 7.8. A simple method of collision detection involves determining whether any of the four corners (A, B, C, and D) of any object exist inside the bounding rectangle of another object.

graphic/07fig08.gif


NOTE

Tip

Consider wrapping this type of geometry in a Point and Rectangle class. The actor's position would then be set using a Point (which would encapsulate x and y). A Rectangle class would then encapsulate a Point along with a width and heightas well as a host of 2D geometry tools, such as the intersection test used earlier for collision detection. The only issue with this approach is the potential cost of two additional classes in your final JAR.

Next you need to add the code that calls this collision detection method into the master cycle of the GameScreen. Here's the complete code for revised cycle method:

protected void cycle()
{
   if (lastCycleTime > 0)
   {
      long msSinceLastCycle = System.currentTimeMillis() - lastCycleTime;

      // cycle all the actors
      for (int i = 0; i < actorList.size(); i++)
      {
         Actor a = (Actor) actorList.elementAt(i);
         a.cycle((int)msSinceLastCycle);

         // check if any hit the wombat
         if (a.isCollidingWith(wombat) && a != wombat)
            running = false;
      }

   }
   lastCycleTime = System.currentTimeMillis();
}

To check for collisions, the cycle code calls the isCollidingWith method on the wombat for every actor. (Make sure you're not checking whether the wombat is colliding with itself.)

    Table of ContentsInput HandlingGame Over