home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / Gamelication / com / next / gt / ActorManager.java < prev    next >
Text File  |  1998-04-15  |  6KB  |  279 lines

  1. /**
  2.  *
  3.  * ActorManager.java
  4.  * @author    Mark G. Tacchi (mtacchi@next.com)
  5.  * @version    0.8
  6.  * Mar 27/1996
  7.  *
  8.  * ActorManager maintains a list of all actors which are participating in
  9.  * the game.  Actors may be added or removed from this list by requesting
  10.  * a change in the list.  When it is safe to make changes to the list,
  11.  * ActorManager will do so.
  12.  *
  13.  * Collision detection is performed in ActorManager.  If Actors collide,
  14.  * a message is sent to each Actor indicating which Actor it has collided
  15.  * with.
  16.  *
  17.  * Queries can be made to ActorManager to determine whether an Actor is in
  18.  * a specific location.
  19. */
  20.  
  21. package com.next.gt;
  22.  
  23. import java.util.Vector;
  24. import java.awt.Rectangle;
  25.  
  26.  
  27. public class ActorManager extends java.lang.Object { 
  28.  
  29.   //
  30.   //  A reference back to the Gamelication this manager is servicing.
  31.   //
  32.   protected Gamelication owner;
  33.   
  34.   //
  35.   //  The list of actors currently alive.  
  36.   //
  37.   public Vector actors= new Vector();
  38.  
  39.   //
  40.   //  The list of actors that will be removed or added when
  41.   //  the current heartbeat is over.
  42.   // 
  43.   private Vector actorsScheduledForRemoval= new Vector();
  44.   private Vector actorsScheduledForInsertion= new Vector();
  45.  
  46.   private boolean    removeAllActors= false;
  47.   
  48. public ActorManager(Gamelication theOwner) {
  49.   owner= theOwner;
  50. }
  51.  
  52.  
  53.  
  54. /**
  55.  * The Actor is added to a list of Actors to be added.
  56.  */
  57. public void addActor (Actor theActor)
  58. {
  59.   actorsScheduledForInsertion.addElement (theActor);
  60. }/*addActor*/
  61.  
  62.  
  63.  
  64. /**
  65.  * The Actor is added to a list of Actors to be removed.
  66.  */
  67. public void removeActor (Actor theActor)
  68. {
  69.   actorsScheduledForRemoval.addElement (theActor);
  70. }/*removeActor*/
  71.  
  72.  
  73.  
  74. /**
  75.  * Dump all references to Actors.  This is used when a game is restarted.
  76.  */
  77. public void removeAllActors ()
  78. {
  79.   //
  80.   // give eventManager a chance to clean up
  81.   //
  82.   for (int i= 0; i< actors.size(); i++) {
  83.     //owner.eventManager.removeFromNotificationRegistry (actors.elementAt (i));
  84.   } /*next_i*/
  85.   
  86.   //
  87.   // destroy pending lists
  88.   //
  89.   actorsScheduledForRemoval.removeAllElements ();
  90.   actorsScheduledForInsertion.removeAllElements ();
  91.   
  92.   //
  93.   // destroy all actors
  94.   //
  95.   actors.removeAllElements ();
  96.  
  97. }/*removeAllActors*/
  98.  
  99.  
  100.  
  101. /**
  102.  * Test if there is an actor at a specified position.
  103.  */
  104. public boolean isActorAt(double theX, double theY) {
  105.   boolean returnValue= false;
  106.      
  107.   for (int i= 0; i < actors.size(); i++){
  108.     Actor anActor= (Actor)actors.elementAt(i);
  109.  
  110.     if (theX >= anActor.x) {
  111.       if ((theX <= (anActor.x + anActor.width)) && 
  112.           (theY >= anActor.y) &&
  113.           (theY <= (anActor.y+anActor.height))) {
  114.         returnValue= true;
  115.       }/*endif*/
  116.     }
  117.     else{
  118.       break;
  119.     }
  120.   }/*next_i*/
  121.     
  122.   return returnValue;
  123. } /*isActorAt*/
  124.  
  125.  
  126.  
  127. /**
  128.  * Test if there is an actor within a specified Rectangle.
  129.  */
  130. public boolean isActorIn(Rectangle theRectangle) {
  131.   boolean returnValue= false;
  132.   double maxxj= theRectangle.x + theRectangle.width;
  133.      
  134.   for (int i= 0; i < actors.size(); i++){
  135.     Actor anActor= (Actor)actors.elementAt(i);
  136.  
  137.     if (maxxj >= anActor.x){
  138.       if (theRectangle.y <= anActor.y){
  139.         if (theRectangle.y + theRectangle.height > anActor.y)
  140.           returnValue= true;
  141.       }
  142.       else{
  143.         if (anActor.y + anActor.height > theRectangle.y)
  144.           returnValue= true;
  145.       }
  146.     }
  147.     else{
  148.       break;
  149.     }
  150.   }/*next_i*/
  151.     
  152.   return returnValue;
  153. } /*isActorIn*/
  154.  
  155.  
  156.  
  157. /**
  158.  * Insertion sort is used to prep Actors for collision detection.  This
  159.  * technique is ideal because actors are almost always already sorted.
  160.  */
  161. private final void sortActorsByXCoordinate()
  162. {
  163.   int i, j;
  164.   int size= actors.size();
  165.  
  166.   for (j= 1; j < size; j++){
  167.      Actor aj= (Actor)actors.elementAt(j);
  168.  
  169.      for (i= j-1; i>=0; i--){        
  170.         Actor ai= (Actor)actors.elementAt(i);
  171.  
  172.         if (aj.x < ai.x)
  173.             actors.setElementAt (ai, i+1);
  174.         else
  175.             break;
  176.      }/*next_i*/
  177.  
  178.      if (j != i+1)
  179.        actors.setElementAt (aj, i+1);
  180.   }/*next_j*/
  181. }/*sortActorsByXCoordinate*/
  182.  
  183.  
  184.  
  185. /*
  186.  * Perform collision detection based on rectangles.  Future versions will
  187.  * detect against circles, and polygons.
  188.  */
  189. private final void detectCollision ()
  190. {
  191.   int i, j;
  192.   int size= actors.size();
  193.  
  194.   for (j= 0; j+1 < size; j++){
  195.     Actor aj= (Actor)actors.elementAt(j);
  196.     double maxxj= aj.x + aj.width;
  197.      
  198.     for (i= j+1; i < size; i++){
  199.       Actor ai = (Actor)actors.elementAt(i);
  200.  
  201.       if (maxxj >= ai.x){
  202.         if (aj.y <= ai.y){
  203.           if (aj.y + aj.height > ai.y)
  204.             handleBBCollision (aj, ai);
  205.         }
  206.         else{
  207.           if (ai.y + ai.height > aj.y)
  208.             handleBBCollision (aj, ai);
  209.         }
  210.       }
  211.       else{
  212.         break;
  213.       }
  214.         
  215.     }/*next_i*/
  216.   }/*next_j*/
  217.   
  218. }/*detectCollision*/
  219.  
  220.  
  221.  
  222. /**
  223.  * Tell each Actor that they've collided with each other.
  224.  */
  225. protected void handleBBCollision (Actor a1, Actor a2)
  226. {
  227.   a1.collideWithActor (a2);
  228.   a2.collideWithActor (a1);
  229. }/*handleBBCollision*/
  230.  
  231.  
  232.  
  233. /**
  234.  * Add/delete Actors, send current Actors a tick message, and then
  235.  * perform collision detection.
  236.  */
  237. public void tick() {
  238.  
  239.   //
  240.   // add all actors which were scheduled for addtion
  241.   //
  242.   if (actorsScheduledForInsertion.size() > 0) {
  243.     for (int i= 0; i < actorsScheduledForInsertion.size(); i++) {
  244.       actors.addElement (actorsScheduledForInsertion.elementAt (i));
  245.     } /*next_i*/      
  246.     actorsScheduledForInsertion.removeAllElements ();
  247.   } /*endif*/
  248.   
  249.   
  250.   //
  251.   // remove all actors which were scheduled for removal
  252.   //
  253.   if (actorsScheduledForRemoval.size() > 0) {
  254.       for (int i= 0; i < actorsScheduledForRemoval.size(); i++) {
  255.         //owner.eventManager.removeFromNotificationRegistry (actorsScheduledForRemoval.elementAt (i));
  256.         actors.removeElement (actorsScheduledForRemoval.elementAt (i));
  257.       } /*next_i*/      
  258.     actorsScheduledForRemoval.removeAllElements ();
  259.   } /*endif*/
  260.  
  261.  
  262.   //
  263.   // send a tick to each actor
  264.   //
  265.   for (int i= 0; i< actors.size (); i++) {
  266.      ((Actor)actors.elementAt(i)).tick();
  267.  } /*next_i*/
  268.  
  269.  
  270.   //
  271.   // perform collision detection
  272.   //
  273.   sortActorsByXCoordinate ();
  274.   detectCollision();
  275.  
  276. } /*tick*/
  277.  
  278. } /*ActorManager*/
  279.