home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / de86gnzn / examples / boink / com / next / gt / actor.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  6.3 KB  |  298 lines

  1.  
  2. /**
  3.  *
  4.  * Actor.java
  5.  * @author    Mark G. Tacchi (mtacchi@next.com) 
  6.  * @version    0.8
  7.  * Feb 23/1996
  8.  *
  9.  * Actor is an abstract superclass which defines behaviour used in the Actors
  10.  * the developer creates.  
  11.  * 
  12.  * Actors are responsible for calculating their positions each tick.  They are
  13.  * also handed a <em>g</em> and expected to draw themselves into it.
  14.  *
  15.  */
  16.  
  17. package com.next.gt;
  18.  
  19. import java.util.Date;
  20. import java.awt.Image;
  21. import java.awt.Graphics;
  22. import java.awt.Rectangle;
  23. import java.applet.Applet;
  24. import java.lang.Math;
  25.  
  26. public abstract class Actor extends java.lang.Object {
  27.  
  28.   //
  29.   // Image and animation variables.
  30.   //
  31.   protected Image    image;
  32.   protected int     numFrames;
  33.   public int     width; 
  34.   public int     height;
  35.   public int     currentFrame;
  36.   protected int     hFrames;
  37.   
  38.   //
  39.   // Position and velocity.
  40.   //
  41.   public double    x, y;
  42.   public double    x_old, y_old;
  43.   public double    velocity_x, velocity_y;
  44.   
  45.   //
  46.   // The object that owns the Actor.
  47.   //
  48.   public Gamelet    owner;
  49.   
  50.   //
  51.   // Flag indicating whether Actor should wrap at edge of screen.
  52.   //
  53.  
  54.  public boolean wrapAround;
  55.  
  56.  
  57. public Actor() {
  58.   currentFrame= 0;
  59.   wrapAround= true;
  60. }
  61. /*Actor()*/
  62.  
  63.  
  64.  
  65. /**
  66.  * Change animation frame, calculate new position, and calculate new velocity..
  67.  */
  68. public void tick() {
  69.   calculateCurrentFrame();
  70.   calculateNewPosition();
  71.   calculateNewVelocity();
  72. } /*tick*/
  73.  
  74.  
  75.  
  76. /**
  77.  * Set the image used for animation.
  78.  */
  79. protected void setImage (Image theImage, 
  80.                  int frameXSize, 
  81.                  int frameYSize, 
  82.                  int framesHorizontally, 
  83.                  int totalFrames)
  84. {
  85.   width= frameXSize; 
  86.   height= frameYSize;
  87.   numFrames= totalFrames;
  88.   hFrames= framesHorizontally;
  89.   image= theImage;
  90.   
  91. } /*setImage(,,,,,)*/
  92.  
  93.  
  94.  
  95. /**
  96.  * Set the image used for animation.  Good for an image that has all frames
  97.  * within it and none empty.
  98.  */
  99. protected void setImage (Image theImage)
  100. {
  101.   int imageHeight;
  102.   int imageWidth;
  103.  
  104.   do { 
  105.     imageHeight= theImage.getHeight (owner);
  106.   } while (imageHeight == -1);
  107.   do {
  108.     imageWidth= theImage.getWidth (owner);
  109.   } while (imageWidth == -1);
  110.  
  111.   setImage (theImage, imageWidth, imageHeight, 1, 1);
  112. }
  113. /*setImage*/
  114.  
  115.  
  116.  
  117. /**
  118.  * Set the image used for animation.  Good for an image that has some empty
  119.  * frames within it.
  120.  */
  121. protected void setImage (Image theImage, 
  122.                  int horizontalFrames, 
  123.                  int totalFrames)
  124. {
  125.   int imageHeight;
  126.   int imageWidth;
  127.  
  128.   do {
  129.     imageHeight= theImage.getHeight (owner);
  130.   } while (imageHeight == -1);
  131.   do {
  132.     imageWidth= theImage.getWidth (owner);
  133.   } while (imageWidth == -1);
  134.    
  135.   setImage (theImage, imageWidth/horizontalFrames, 
  136.              imageHeight / (int)Math.ceil((double)totalFrames/(double)horizontalFrames),
  137.              horizontalFrames,
  138.              totalFrames 
  139.             );
  140. }
  141. /*setImage,,,*/
  142.  
  143.  
  144.  
  145. /**
  146.  * Calculates the new X and Y position based on velocity and time.  Also may check if
  147.  * Actor needs to wrap around at the edges if the <em>wraparound</em> flag is set.
  148.  */
  149. protected void calculateNewPosition() {
  150.  
  151.   double    deltaTime= owner.deltaTickTimeMillis()/1000.0;
  152.  
  153.   //
  154.   // save old position
  155.   //
  156.   x_old= x;
  157.   y_old= y;
  158.   
  159.   //
  160.   // calculate position based on velocity and time
  161.   //
  162.   x+= velocity_x*deltaTime;
  163.   y+= velocity_y*deltaTime;
  164.   
  165.  
  166.  if (wrapAround) checkForOutOfBounds();
  167.  
  168. } /*calculateNewPosition*/
  169.  
  170.  
  171.  
  172. /**
  173.  * Override this to provide your own behaviour.
  174.  */
  175. protected void calculateNewVelocity() {
  176. }
  177.     
  178.     
  179.     
  180. /**
  181.  * Calculates the current frame.  Behaviour is to flip through frames sequentially
  182.  * and loop.
  183.  */
  184. protected void calculateCurrentFrame() {
  185.   if (++currentFrame>=numFrames) currentFrame= 0;
  186. } /*calculateCurrentFrame*/
  187.  
  188.  
  189.  
  190. /**
  191.  * Check for out of bounds and wrap if it is.
  192.  */
  193. protected void checkForOutOfBounds() {
  194.  
  195.   //
  196.   // check for out of bounds and wrap
  197.   //
  198.   if (x > (owner.size().width + width + width)) {
  199.     x= -width;
  200.   }
  201.   else if (x < -width) {
  202.     x= owner.size().width + width + width;
  203.   }
  204.   
  205.   if (y > (owner.size().height + height + height)) {
  206.     y= -height;
  207.   
  208.   }
  209.   else if (y < -height) {
  210.     y= owner.size().height + height + height;
  211.   }
  212.   
  213. } /*checkForOutOfBounds*/
  214.  
  215.  
  216.  
  217. /**
  218.  * Each Actor is handed a <em>g</em> and is expected to draw itself in it.
  219.  */ 
  220. public void draw (Graphics g)
  221. {
  222.   double    offsetx= -(currentFrame%hFrames)*width;
  223.   double    offsety= -Math.floor(currentFrame/hFrames) * height;
  224.  
  225.   Graphics     g2= g.create ((int)x, (int)y, width, height);
  226.   g2.drawImage(image, (int)offsetx, (int)offsety, owner);
  227.   g2.dispose ();
  228.  
  229. }
  230. /*draw*/
  231.  
  232.  
  233.  
  234. /**
  235.  * Override this method to handle the case when Actor collides with another.
  236.  */ 
  237. protected void collideWithActor (Actor theActor){
  238. } /*collideWithActor*/
  239.  
  240.  
  241.  
  242. /**
  243.  * Bounce off the specified Actor.  Changes it's velocity so that it appears
  244.  * to bounce off.
  245.  */ 
  246. public void bounceOff(Actor theActor) {
  247.   double        myCenterX= width/2 + x_old, myCenterY= height/2 + y_old;
  248.   double        actorCenterX= theActor.width/2 + theActor.x;
  249.   double        actorCenterY= theActor.height/2 + theActor.y;
  250.   double    slope= (myCenterY - actorCenterY)/(myCenterX - actorCenterX);    
  251.   double        b= myCenterY - slope*myCenterX;
  252.   
  253.  
  254.   double        intersectY, intersectX;
  255.     
  256.   //
  257.   // Check if segments intersect.
  258.   //
  259.   
  260.   //
  261.   // Check RIGHT side
  262.   //
  263.   if (theActor.x>=myCenterX) {
  264.     intersectY= slope*theActor.x + b;
  265.     if (intersectY>=theActor.y && intersectY<=theActor.y+theActor.height) {
  266.       velocity_x= theActor.velocity_x - velocity_x;
  267.       x= x_old;
  268.     } /*endif*/
  269.   }
  270.   //
  271.   // Check LEFT side
  272.   //
  273.   else if (theActor.x+theActor.width<=myCenterX) {
  274.     intersectY= slope*(theActor.x + theActor.width) + b;
  275.     if (intersectY>=theActor.y && intersectY<=theActor.y+theActor.height) {
  276.       velocity_x= theActor.velocity_x - velocity_x;
  277.       x= x_old;
  278.     } /*endif*/
  279.   }
  280.   
  281.   //
  282.   // Check BOTTOM side
  283.   //
  284.   else if (theActor.y>=myCenterY) {
  285.     intersectX= (theActor.y - b)/slope;
  286.     if (intersectX>=theActor.x && intersectX<=theActor.x+theActor.width) {
  287.       velocity_y= theActor.velocity_y - velocity_y;
  288.       y= y_old;
  289.     } /*endif*/
  290.   }
  291.   //
  292.   // Check TOP side
  293.   //
  294.   else if (theActor.y+theActor.height<=myCenterY) {
  295.     intersectX= (theActor.y + theActor.height - b)/slope;
  296.     if (intersectX>=theActor.x && intersectX<=theActor.x+theActor.width) {
  297.       velocity_y= theActor.velocity_y - velocity_y;
  298.       y= y_old;
  299.     } /*endif*/
  300.   }
  301.   
  302. } /*bounceOff*/
  303.  
  304. } /*BOActor*/
  305.  
  306.  
  307.  
  308.  
  309.  
  310.