scg/ch06/PongBall

From FANG

Jump to: navigation, search

001 package scg.ch06;
002 
003 import fang2.core.Game;
004 import fang2.core.Sprite;
005 import fang2.sprites.OvalSprite;
006 
007 /**
008  * The PongBall is an augmented {@link fang2.sprites.OvalSprite
009  * OvalSprite} which has a velocity, an advance method which applies
010  * that velocity, and the ability to bounce off of the walls of the game
011  * and other sprites.
012  */
013 public class PongBall
014   extends OvalSprite {
015   /**
016    * current velocity in screens/second; decomposed into x-coordinate
017    * and y-coordinate velocities
018    */
019   private double deltaX;
020   private double deltaY;
021 
022   /**
023    * Create a new PongBall. Specify the size and the initial velocity of
024    * the ball.
025    *
026    @param  width   width of the ball in screens
027    @param  height  height of the ball in screens
028    @param  deltaX  initial horizontal velocity in screens per second
029    @param  deltaY  initial vertical velocity in screens per second
030    */
031   public PongBall(double width, double height, 
032                   double deltaX, double deltaY{
033     super(width, height);
034     // A scope hole: two detltaX are in scope (line 9, line 25)
035     // Deepest nested block in scope wins: line 25
036     // this.deltaX refers to the field (line 9)
037     this.deltaX = deltaX;// set FIELD to the parameter value
038     this.deltaY = deltaY;// set FIELD to the parameter value
039   }
040 
041   /**
042    * Create a new PongBall. Specify the size of the ball.
043    *
044    @param  width   width of the ball in screens
045    @param  height  height of the ball in screens
046    */
047   public PongBall(double width, double height{
048     this(width, height, 0.00.0);
049   }
050 
051   /**
052    * Update this ball's position on the screen. This moves the
053    * responsibility for updating the ball's position out of the {@link
054    * fang2.core.Game Game} class's {@code advance} method. This is a
055    * good division of responsibilities: the ball knows its speed and
056    * whatever else it needs to know.
057    *
058    @param  deltaT  time elapsed since the last call to advance in
059    *                 seconds
060    */
061   public void advance(double deltaT, Sprite paddle{
062     translate(deltaX * deltaT, deltaY * deltaT);
063     bounceOffEdges();
064     if (intersects(paddle)) {
065       bounceOffSprite(paddle);
066       incrementScore();
067     }
068   }
069 
070   /**
071    * Has the ball hit a scoring/out of bounds line?
072    *
073    @return  true if out of bounds; false otherwise
074    */
075   public boolean isOutOfBounds() {
076     return hitRightEdge();
077   }
078 
079   /**
080    Set the velocity of this ball to the given x and y values.
081    *
082    @param  deltaX  horizontal velocity of the ball (screens/sec)
083    @param  deltaY  vertical velocity of the ball (screens/sec)
084    */
085   public void setVelocity(double deltaX, double deltaY{
086     this.deltaX = deltaX;
087     this.deltaY = deltaY;
088   }
089 
090   /**
091    * Is this sprite above the other?
092    *
093    @param   other  sprite to test against
094    *
095    @return  true if this's center is above other; false otherwise
096    */
097   private boolean aboveIt(Sprite other{
098     return (getY() < other.getMinY());
099   }
100 
101   /**
102    * Is this sprite below other?
103    *
104    @param   other  sprite to test against
105    *
106    @return  true if this's center is below other; false otherwise
107    */
108   private boolean belowIt(Sprite other{
109     return (other.getMaxY() < getY());
110   }
111 
112   /**
113    * Bounce the ball off all walls off which it bounces.
114    */
115   private void bounceOffEdges() {
116     if (hitTopEdge()) {
117       bounceOffHorizontalEdge();
118       clearTop(0.0);
119     } else if (hitBottomEdge()) {
120       bounceOffHorizontalEdge();
121       clearBottom(1.0);
122     }
123     if (hitLeftEdge()) {
124       bounceOffVerticalEdge();
125       clearLeft(0.0);
126     }
127     /* else if (hitRightEdge()) {
128      * clearRight(1.0);} */
129   }
130 
131   /**
132    * Respond to hitting a horizontal edge; reverse the up/down direction
133    * (by changing the sign of deltaY).
134    */
135   private void bounceOffHorizontalEdge() {
136     deltaY = -deltaY;
137   }
138 
139   /**
140    * A ball collides with any other sprite, treat the other as a
141    * rectangle, bounce off the horizontal/vertical surfaces (or both).
142    * Only reverse direction if you were moving "into" the paddle in the
143    * given direction.
144    *
145    <p>If the other is on our right AND it intersects our right edge,
146    * then we were moving toward it when we hit. Need to reverse. If,
147    * instead, it is on our right and somehow our left edge intersects
148    * (or seems to), we actually hit the top or bottom edge and there is
149    * no reversal in the x-dimension.
150    *
151    @param  other  the other sprite which we hit
152    */
153   private void bounceOffSprite(Sprite other{
154     if (leftOfIt(other&& intersectsRight(other)) {
155       bounceOffVerticalEdge();
156       clearRight(other.getMinX());
157     }
158     if (rightOfIt(other&& intersectsLeft(other)) {
159       bounceOffVerticalEdge();
160       clearLeft(other.getMaxX());
161     }
162 
163     if (aboveIt(other&& intersectsBottom(other)) {
164       bounceOffHorizontalEdge();
165       clearBottom(other.getMinY());
166     }
167     if (belowIt(other&& intersectsTop(other)) {
168       bounceOffHorizontalEdge();
169       clearTop(other.getMaxY());
170     }
171   }
172 
173   /**
174    * Respond to hitting a vertical edge; reverse the left/right
175    * direction (by changing the sign of deltaX).
176    */
177   private void bounceOffVerticalEdge() {
178     deltaX = -deltaX;
179   }
180 
181   /**
182    * Make sure our bottom edge is clear of y
183    *
184    @param  y  the line we must be above
185    */
186   private void clearBottom(double y{
187     if (y < getMaxY()) {
188       translateY(y - getMaxY());
189     }
190   }
191 
192   /**
193    * Make sure our left edge is clear of x
194    *
195    @param  x  the line we must be to the right of
196    */
197   private void clearLeft(double x{
198     if (getMinX() < x{
199       translateX(x - getMinX());
200     }
201   }
202 
203   /**
204    * Make sure our right edge is clear of x
205    *
206    @param  x  the line we must be to the left of
207    */
208   private void clearRight(double x{
209     if (x < getMaxX()) {
210       translateY(x - getMaxX());
211     }
212   }
213 
214   /**
215    * Make sure our top edge is clear of the given y
216    *
217    @param  y  the line we must be below
218    */
219   private void clearTop(double y{
220     if (getMinY() < y{
221       translateY(y - getMinY());
222     }
223   }
224 
225   /**
226    * Did the ball hit the bottom edge?
227    *
228    @return  true if the ball hit the bottom edge
229    */
230   private boolean hitBottomEdge() {
231     return (getMaxY() >= 1.0);
232   }
233 
234   /**
235    * Did the ball hit the left edge?
236    *
237    @return  true if it hit the left edge
238    */
239   private boolean hitLeftEdge() {
240     return (getMinX() <= 0.0);
241   }
242 
243   /**
244    * Did the ball hit the right edge?
245    *
246    @return  true if it has hit the right edge
247    */
248   private boolean hitRightEdge() {
249     return (getMaxX() >= 1.0);
250   }
251 
252   /**
253    * Did the ball hit the top edge?
254    *
255    @return  true if the ball hit the top edge
256    */
257   private boolean hitTopEdge() {
258     return (getMinY() <= 0.0);
259   }
260 
261   /**
262    * Add one to the game's score.
263    */
264   private void incrementScore() {
265     Game.getCurrentGame().
266     setScore(Game.getCurrentGame().getScore() + 1);
267   }
268   
269   /**
270    * Does other intersect our bottom edge?
271    *
272    @param   other  sprite to test against
273    *
274    @return  true if given edge intersects; false otherwise
275    */
276   private boolean intersectsBottom(Sprite other{
277     return (other.getMinY() < getMaxY());
278   }
279 
280   /**
281    * Does other intersect our left edge?
282    *
283    @param   other  sprite to test against
284    *
285    @return  true if given edge intersects; false otherwise
286    */
287   private boolean intersectsLeft(Sprite other{
288     return (getMinX() < other.getMaxX());
289   }
290 
291   /**
292    * Does other intersect our right edge?
293    *
294    @param   other  sprite to test against
295    *
296    @return  true if given edge intersects; false otherwise
297    */
298   private boolean intersectsRight(Sprite other{
299     return (other.getMinX() < getMaxX());
300   }
301 
302   /**
303    * Does other intersect our top edge?
304    *
305    @param   other  sprite to test against
306    *
307    @return  true if given edge intersects; false otherwise
308    */
309   private boolean intersectsTop(Sprite other{
310     return (getMinY() < other.getMaxY());
311   }
312 
313   /**
314    * Is this sprite to the left of other?
315    *
316    @param   other  the sprite to test against
317    *
318    @return  true if this's center is to the left of other; false
319    *          otherwise
320    */
321   private boolean leftOfIt(Sprite other{
322     return (getX() < other.getMinX());
323   }
324 
325   /**
326    * Is this sprite to the right of other?
327    *
328    @param   other  the sprite to test against
329    *
330    @return  true if this's center is to the right of other; false
331    *          otherwise
332    */
333   private boolean rightOfIt(Sprite other{
334     return (other.getMaxX() < getX());
335   }
336 }
337 
338 //Uploaded on Mon Mar 29 21:39:34 EDT 2010


Download/View scg/ch06/PongBall.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