home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / de86gnzn / examples / boink / com / next / gt / actormanager.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  6.1 KB  |  278 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 Gamelet this manager is servicing.
  31.   //
  32.   protected Gamelet 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(Gamelet 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. }
  61. /*addActor*/
  62.  
  63.  
  64.  
  65. /**
  66.  * The Actor is added to a list of Actors to be removed.
  67.  */
  68. public void removeActor (Actor theActor)
  69. {
  70.   actorsScheduledForRemoval.addElement (theActor);
  71. }
  72. /*removeActor*/
  73.  
  74.  
  75.  
  76. /**
  77.  * Dump all references to Actors.  This is used when a game is restarted.
  78.  */
  79. public void removeAllActors ()
  80. {
  81.   //
  82.   // give eventManager a chance to clean up
  83.   //
  84.   for (int i= 0; i< actors.size(); i++) {
  85.     owner.eventManager.removeFromNotificationRegistry (actors.elementAt (i));
  86.   } /*next_i*/
  87.   
  88.   //
  89.   // destroy pending lists
  90.   //
  91.   actorsScheduledForRemoval.removeAllElements ();
  92.   actorsScheduledForInsertion.removeAllElements ();
  93.   
  94.   //
  95.   // destroy all actors
  96.   //
  97.   actors.removeAllElements ();
  98.  
  99. }
  100. /*removeAllActors*/
  101.  
  102.  
  103.  
  104. /**
  105.  * Test if there is an actor at a specified position.
  106.  */
  107. public boolean isActorAt(double theX, double theY) {
  108.   boolean returnValue= false;
  109.      
  110.   for (int i= 0; i < actors.size(); i++)
  111. {
  112.     Actor anActor= (Actor)actors.elementAt(i);
  113.  
  114.     if (theX >= anActor.x) {
  115.       if ((theX <= (anActor.x + anActor.width)) && 
  116.           (theY >= anActor.y) &&
  117.           (theY <= (anActor.y+anActor.height))) {
  118.         returnValue= true;
  119.       }
  120. /*endif*/
  121.     }
  122.     else
  123. {
  124.       break;
  125.     }
  126.   }
  127. /*next_i*/
  128.     
  129.   return returnValue;
  130. } /*isActorAt*/
  131.  
  132.  
  133.  
  134. /**
  135.  * Test if there is an actor within a specified Rectangle.
  136.  */
  137. public boolean isActorIn(Rectangle theRectangle) {
  138.   boolean returnValue= false;
  139.   double maxxj= theRectangle.x + theRectangle.width;
  140.      
  141.   for (int i= 0; i < actors.size(); i++)
  142. {
  143.     Actor anActor= (Actor)actors.elementAt(i);
  144.  
  145.     if (maxxj >= anActor.x)
  146. {
  147.       if (theRectangle.y <= anActor.y)
  148. {
  149.         if (theRectangle.y + theRectangle.height > anActor.y)
  150.           returnValue= true;
  151.       }
  152.       else
  153. {
  154.         if (anActor.y + anActor.height > theRectangle.y)
  155.           returnValue= true;
  156.       }
  157.     }
  158.     else
  159. {
  160.       break;
  161.     }
  162.   }
  163. /*next_i*/
  164.     
  165.   return returnValue;
  166. } /*isActorIn*/
  167.  
  168.  
  169.  
  170. /**
  171.  * Insertion sort is used to prep Actors for collision detection.  This
  172.  * technique is ideal because actors are almost always already sorted.
  173.  */
  174. private final void sortActorsByXCoordinate()
  175. {
  176.   int i, j;
  177.   int size= actors.size();
  178.  
  179.   for (j= 1; j < size; j++)
  180. {
  181.      Actor aj= (Actor)actors.elementAt(j);
  182.  
  183.      for (i= j-1; i>=0; i--)
  184. {        
  185.         Actor ai= (Actor)actors.elementAt(i);
  186.  
  187.         if (aj.x < ai.x)
  188.             actors.setElementAt (ai, i+1);
  189.         else
  190.             break;
  191.      }
  192. /*next_i*/
  193.  
  194.      if (j != i+1)
  195.        actors.setElementAt (aj, i+1);
  196.   }
  197. /*next_j*/
  198. }
  199. /*sortActorsByXCoordinate*/
  200.  
  201.  
  202.  
  203. /*
  204.  * Perform collision detection based on rectangles.  Future versions will
  205.  * detect against circles, and polygons.
  206.  */
  207. private final void detectCollision ()
  208. {
  209.   int i, j;
  210.   int size= actors.size();
  211.  
  212.   for (j= 0; j+1 < size; j++)
  213. {
  214.     Actor aj= (Actor)actors.elementAt(j);
  215.     double maxxj= aj.x + aj.width;
  216.      
  217.     for (i= j+1; i < size; i++)
  218. {
  219.       Actor ai = (Actor)actors.elementAt(i);
  220.  
  221.       if (maxxj >= ai.x)
  222. {
  223.         if (aj.y <= ai.y)
  224. {
  225.           if (aj.y + aj.height > ai.y)
  226.             handleBBCollision (aj, ai);
  227.         }
  228.         else
  229. {
  230.           if (ai.y + ai.height > aj.y)
  231.             handleBBCollision (aj, ai);
  232.         }
  233.       }
  234.       else
  235. {
  236.         break;
  237.       }
  238.         
  239.     }
  240. /*next_i*/
  241.   }
  242. /*next_j*/
  243.   
  244. }
  245. /*detectCollision*/
  246.  
  247.  
  248.  
  249. /**
  250.  * Tell each Actor that they've collided with each other.
  251.  */
  252. protected void handleBBCollision (Actor a1, Actor a2)
  253. {
  254.   a1.collideWithActor (a2);
  255.   a2.collideWithActor (a1);
  256. }
  257. /*handleBBCollision*/
  258.  
  259.  
  260.  
  261. /**
  262.  * Add/delete Actors, send current Actors a tick message, and then
  263.  * perform collision detection.
  264.  */
  265. public void tick() {
  266.  
  267.  
  268.   //
  269.   // add all actors which were scheduled for addtion
  270.   //
  271.   if (actorsScheduledForInsertion.size() > 0) {
  272.     for (int i= 0; i < actorsScheduledForInsertion.size(); i++) {
  273.       actors.addElement (actorsScheduledForInsertion.elementAt (i));
  274.     } /*next_i*/      
  275.     actorsScheduledForInsertion.removeAllElements ();
  276.   } /*endif*/
  277.   
  278.   
  279.   //
  280.   // remove all actors which were scheduled for removal
  281.   //
  282.   if (actorsScheduledForRemoval.size() > 0) {
  283.       for (int i= 0; i < actorsScheduledForRemoval.size(); i++) {
  284.         owner.eventManager.removeFromNotificationRegistry (actorsScheduledForRemoval.elementAt (i));
  285.         actors.removeElement (actorsScheduledForRemoval.elementAt (i));
  286.       } /*next_i*/      
  287.     actorsScheduledForRemoval.removeAllElements ();
  288.   } /*endif*/
  289.  
  290.  
  291.   //
  292.   // send a tick to each actor
  293.   //
  294.   for (int i= 0; i< actors.size (); i++) {
  295.      ((Actor)actors.elementAt(i)).tick();
  296.  
  297.  } /*next_i*/
  298.  
  299.  
  300.   //
  301.   // perform collision detection
  302.   //
  303.   sortActorsByXCoordinate ();
  304.   detectCollision();
  305.  
  306. } /*tick*/
  307.  
  308. } /*ActorManager*/