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

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