001 package com.croftsoft.apps.dodger;
002
003 import java.applet.*;
004 import java.awt.*;
005 import java.awt.event.*;
006 import java.awt.geom.*;
007 import java.util.Random;
008 import javax.swing.*;
009 import javax.swing.event.*;
010
011 import com.croftsoft.core.lang.NullArgumentException;
012 import com.croftsoft.core.animation.*;
013 import com.croftsoft.core.animation.sprite.*;
014
015 /*********************************************************************
016 * An IconSprite subclass representing a Dodger obstacle.
017 *
018 * @version
019 * 2002-03-23
020 * @since
021 * 2002-03-18
022 * @author
023 * <a href="https://www.croftsoft.com/">David Wallace Croft</a>
024 *********************************************************************/
025
026 public class ObstacleSprite
027 extends AbstractSprite
028 //////////////////////////////////////////////////////////////////////
029 //////////////////////////////////////////////////////////////////////
030 {
031
032 private static final int OBSTACLE_WIDTH = 32;
033
034 private static final int OBSTACLE_HEIGHT = 32;
035
036 private static final long EXPLODE_PERIOD_MILLIS = 1000;
037
038 //
039
040 private final AudioClip explodeAudioClip;
041
042 private final Random random;
043
044 private final Rectangle bounds;
045
046 private final int pixelsPerFrame;
047
048 private final Rectangle paintBounds;
049
050 //
051
052 private Color color;
053
054 private long explodeTimeMillis;
055
056 private boolean hit;
057
058 private boolean exploding;
059
060 //////////////////////////////////////////////////////////////////////
061 // constructor methods
062 //////////////////////////////////////////////////////////////////////
063
064
065 public ObstacleSprite (
066 AudioClip explodeAudioClip,
067 Random random,
068 Rectangle bounds,
069 int pixelsPerFrame )
070 //////////////////////////////////////////////////////////////////////
071 {
072 NullArgumentException.check (
073 this.explodeAudioClip = explodeAudioClip );
074
075 NullArgumentException.check ( this.random = random );
076
077 NullArgumentException.check ( this.bounds = bounds );
078
079 this.pixelsPerFrame = pixelsPerFrame;
080
081 paintBounds = new Rectangle (
082 0, 0, OBSTACLE_WIDTH, OBSTACLE_HEIGHT );
083
084 setY ( Double.POSITIVE_INFINITY );
085
086 color = new Color (
087 random.nextInt ( 256 ),
088 random.nextInt ( 256 ),
089 random.nextInt ( 256 ) );
090 }
091
092 //////////////////////////////////////////////////////////////////////
093 // accessor methods
094 //////////////////////////////////////////////////////////////////////
095
096 public void getPaintBounds ( Rectangle paintBounds )
097 //////////////////////////////////////////////////////////////////////
098 {
099 paintBounds.setBounds ( this.paintBounds );
100 }
101
102 public Shape getCollisionShape ( )
103 //////////////////////////////////////////////////////////////////////
104 {
105 if ( exploding )
106 {
107 return null;
108 }
109
110 return paintBounds;
111 }
112
113 //////////////////////////////////////////////////////////////////////
114 // mutator methods
115 //////////////////////////////////////////////////////////////////////
116
117 public void setX ( double x )
118 //////////////////////////////////////////////////////////////////////
119 {
120 super.setX ( x );
121
122 paintBounds.x = ( int ) Math.round ( x );
123 }
124
125 public void setY ( double y )
126 //////////////////////////////////////////////////////////////////////
127 {
128 super.setY ( y );
129
130 paintBounds.y = ( int ) Math.round ( y );
131 }
132
133 public void setHit ( )
134 //////////////////////////////////////////////////////////////////////
135 {
136 hit = true;
137 }
138
139 public void reset ( )
140 //////////////////////////////////////////////////////////////////////
141 {
142 hit = false;
143
144 exploding = false;
145
146 setX ( -OBSTACLE_WIDTH
147 + random.nextInt ( bounds.width + OBSTACLE_WIDTH ) );
148
149 setY ( -random.nextInt ( bounds.height ) - OBSTACLE_HEIGHT );
150
151 color = new Color (
152 random.nextInt ( 256 ),
153 random.nextInt ( 256 ),
154 random.nextInt ( 256 ) );
155 }
156
157 //////////////////////////////////////////////////////////////////////
158 // interface ComponentAnimator methods
159 //////////////////////////////////////////////////////////////////////
160
161 public void update ( JComponent component )
162 //////////////////////////////////////////////////////////////////////
163 {
164 long updateTimeMillis = System.currentTimeMillis ( );
165
166 double y = getY ( );
167
168 y += pixelsPerFrame;
169
170 if ( y >= bounds.height )
171 {
172 reset ( );
173 }
174 else
175 {
176 setY ( y );
177 }
178
179 if ( exploding )
180 {
181 if ( updateTimeMillis
182 >= explodeTimeMillis + EXPLODE_PERIOD_MILLIS )
183 {
184 reset ( );
185 }
186
187 color = new Color (
188 random.nextInt ( 256 ),
189 random.nextInt ( 256 ),
190 random.nextInt ( 256 ) );
191 }
192 else if ( hit )
193 {
194 explodeAudioClip.play ( );
195
196 color = new Color (
197 random.nextInt ( 256 ),
198 random.nextInt ( 256 ),
199 random.nextInt ( 256 ) );
200
201 explodeTimeMillis = updateTimeMillis;
202
203 exploding = true;
204 }
205 }
206
207 public void paint (
208 JComponent component,
209 Graphics2D graphics )
210 //////////////////////////////////////////////////////////////////////
211 {
212 graphics.setColor ( color );
213
214 graphics.fillRect (
215 paintBounds.x,
216 paintBounds.y,
217 OBSTACLE_WIDTH,
218 OBSTACLE_HEIGHT );
219
220 graphics.setColor ( Color.BLACK );
221
222 graphics.drawRect (
223 paintBounds.x,
224 paintBounds.y,
225 OBSTACLE_WIDTH,
226 OBSTACLE_HEIGHT );
227 }
228
229 //////////////////////////////////////////////////////////////////////
230 //////////////////////////////////////////////////////////////////////
231 }