scg/ch09/Swimmer

From FANG

Jump to: navigation, search

001 package scg.ch09;
002 
003 import java.awt.Color;
004 
005 import fang2.attributes.Palette;
006 import fang2.sprites.OvalSprite;
007 import fang2.sprites.RectangleSprite;
008 
009 /**
010  * The characters that need to be rescued. These folk will wave their
011  * "arms" as they move back and forth across the screen.
012  */
013 public class Swimmer
014   extends SpriteWithVelocity {
015   /** shared bump flag: NOT final */
016   private static boolean bumpedTheWall = false;
017 
018   /** Number of different animation frames */
019   private static final int FRAME_COUNT = 4;
020 
021   /** Offsets for the left and right arm, respectively */
022   private static final double leftArmX = -0.12;
023   private static final double leftArmY = -0.25;
024 
025   private static final double rightArmX = 0.12;
026   private static final double rightArmY = -0.25;
027 
028   /** How long should each animation frame last? */
029   private static final double SECONDS_PER_FRAME = 0.25;
030 
031   /** Which animation frame is currently showing? */
032   private int frame;
033 
034   /** the value of this swimmer if rescued; immutable */
035   private final int score;
036 
037   /** The internal parts of the swimmer's body */
038   private final OvalSprite swimmerBody;
039 
040   private final RectangleSprite swimmerLeftArm;
041 
042   private final RectangleSprite swimmerRightArm;
043 
044   /** animation timer; expires with call to timerExpried */
045   protected double timer;
046 
047   /**
048    * Create a new swimmer with given score and velocity.
049    *
050    @param  score   the score for rescuing this swimmer
051    @param  deltaX  initial horizontal velocity (in screens/sec)
052    @param  deltaY  initial vertical velocity (in screens/sec)
053    */
054   public Swimmer(int score, double deltaX, double deltaY{
055     super(deltaX, deltaY);
056     this.score = score;
057     swimmerRightArm = makeArm(rightArmX, rightArmY);
058     swimmerLeftArm = makeArm(leftArmX, leftArmY);
059     swimmerBody = new OvalSprite(0.50.5);
060     swimmerBody.setLocation(0.00.0);
061     addSprite(swimmerBody);
062 
063     frame = 0;// setFrame(int) rotates the sprite
064     startTimer();
065   }
066 
067   /**
068    * Called when some swimmer bumps the wall. This is static so that all
069    * swimmers share the same flag (so all bounce as one unit)
070    */
071   public static void bumpTheWall() {
072     bumpedTheWall = true;
073   }
074 
075   /**
076    * Called when bumping the wall is "serviced". This makes sure that
077    * the swimmers are ready to bounce off the next wall.
078    */
079   public static void clearBumpTheWall() {
080     bumpedTheWall = false;
081   }
082 
083   /**
084    * Get the bumped-the-wall flag.
085    *
086    @return  true if the wall was bumped (and not cleared); false
087    *          otherwise
088    */
089   public static boolean hasBumpedTheWall() {
090     return bumpedTheWall;
091   }
092 
093   /**
094    * Move swimmer and set a wall-hit flag if this swimmer has touched a
095    * wall. Uses super.advance(double) and decrementTimer(double): ALL
096    * subclasses of Swimmer must call decrementTimer in advance.
097    *
098    @param  dT  seconds since the last frame update
099    */
100   @Override
101   public void advance(double dT{
102     super.advance(dT);
103     decrementTimer(dT);
104     if (runIntoLeftWall() || runIntoRightWall()) {
105       bumpTheWall();
106     }
107   }
108 
109   /**
110    * Bounce this swimmer off the wall. If any swimmer has struck the
111    * wall, reverse movement and move down the screen.
112    */
113   @Override
114   public void bounceOffEdges() {
115     if (hasBumpedTheWall()) {
116       reverseVelocity();
117       setY(getY() + (getHeight() 2));
118     }
119   }
120 
121   /**
122    * Get the score value of this swimmer.
123    *
124    @return  the initially set value of the score.
125    */
126   public int getScore() {
127     return score;
128   }
129 
130   /**
131    Set the color of this sprite (actually the body of the sprite).
132    */
133   @Override
134   public void setColor(Color color{
135     swimmerBody.setColor(color);
136   }
137 
138   /**
139    * Create a new arm. Arms are rectangle sprites with a given offset
140    * and scale. This method is used to create one arm centered at the
141    * given coordinates.
142    *
143    @param   xCoordinate  horizontal center (in CompositeSprite
144    *                       coordinates) of arm
145    @param   yCoordinate  vertical center (in CompositeSprite
146    *                       coordinates) of arm
147    *
148    @return
149    */
150   private RectangleSprite makeArm(double xCoordinate,
151     double yCoordinate{
152     RectangleSprite theArm = new RectangleSprite(0.10.25);
153     theArm.setLocation(xCoordinate, yCoordinate);
154     theArm.setColor(Palette.getColor("goldenrod"));
155     addSprite(theArm);
156     return theArm;
157   }
158 
159   /**
160    * Decrement the timer; this timer is used for handling animation
161    *
162    @param  dT  seconds since the last frame update
163    */
164   protected void decrementTimer(double dT{
165     timer -= dT;
166     if (timer <= 0{
167       timerExpired();
168       startTimer();
169     }
170   }
171 
172   /**
173    * Return the length of time the timer should use.
174    *
175    @return  seconds before the timer should expire.
176    */
177   protected double getTimerCountdownTime() {
178     return SECONDS_PER_FRAME;
179   }
180 
181   /**
182    Set the animation frame number to the given frame number. Updates
183    * the position of the sprite to match the given frame number
184    *
185    @param  frameNumber  the new frame number; will be mapped onto
186    *                      [0-FRAME_COUNT)
187    */
188   protected void setFrame(int frameNumber{
189     frame = frameNumber % FRAME_COUNT;
190     if (frame == 0{
191       rotate(20);
192     } else if (frame == 1{
193       rotate(20);
194     } else if (frame == 2{
195       rotate(-20);
196     } else if (frame == 3{
197       rotate(-20);
198     }
199   }
200 
201   /**
202    Set the timer's countdown value.
203    *
204    @param  timer  seconds to count down
205    */
206   protected void setTimer(double timer{
207     this.timer = timer;
208   }
209 
210   /**
211    Set the timer to the value given by getTimerCountdownTime.
212    */
213   protected void startTimer() {
214     setTimer(getTimerCountdownTime());
215   }
216 
217   /**
218    * What "happens" when the timer expires. This one just sets the frame
219    * to the next frame, updating the animation.
220    */
221   protected void timerExpired() {
222     setFrame((frame + 1% FRAME_COUNT);
223   }
224 }
225 
226 //Uploaded on Mon Mar 29 21:39:58 EDT 2010


Download/View scg/ch09/Swimmer.java





Views
Personal tools
Add to 
del.icio.usAdd to 
diggAdd to 
FacebookAdd to 
favoritesAdd to 
GoogleAdd to 
MySpaceAdd to 
PrintAdd to 
SlashdotAdd to 
StumbleUponAdd to 
Twitter

Games
Games