001         package com.croftsoft.apps.road;
002         
003         import java.applet.*;
004         import java.awt.*;
005         import java.awt.event.*;
006         import java.awt.geom.*;
007         import java.io.*;
008         import java.net.URL;
009         import java.util.*;
010         import javax.swing.*;
011         import javax.swing.event.*;
012    
013         import com.croftsoft.core.animation.AnimatedApplet;
014         import com.croftsoft.core.animation.AnimationInit;
015         import com.croftsoft.core.animation.animator.TileAnimator;
016         import com.croftsoft.core.animation.clock.HiResClock;
017         import com.croftsoft.core.animation.clock.Timekeeper;
018         import com.croftsoft.core.animation.controller.FrameRateController;
019         import com.croftsoft.core.animation.icon.ColorTileIcon;
020         import com.croftsoft.core.animation.model.seri.SeriModelId;
021         import com.croftsoft.core.animation.painter.ColorPainter;
022         import com.croftsoft.core.animation.painter.IconPainter;
023         import com.croftsoft.core.animation.painter.TilePainter;
024         import com.croftsoft.core.animation.sprite.IconSprite;
025         import com.croftsoft.core.awt.image.ImageLib;
026         import com.croftsoft.core.gui.event.UserInputAdapter;
027    //   import com.croftsoft.core.media.sound.AudioClipCache;
028    
029         import com.croftsoft.apps.road.model.Car;
030         import com.croftsoft.apps.road.model.seri.SeriCar;
031    
032         /*********************************************************************
033         * CroftSoft Roadrunner main class.
034         *
035         * @version
036         *   2003-09-10
037         * @since
038         *   2003-07-02
039         * @author
040         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
041         *********************************************************************/
042    
043         public final class  Main
044           extends AnimatedApplet
045           implements Constants
046         //////////////////////////////////////////////////////////////////////
047         //////////////////////////////////////////////////////////////////////
048         {
049    
050         private final Rectangle   componentBounds;
051    
052         private final Rectangle   tileArea;
053    
054         private final Rectangle   leftBorderArea;
055    
056         private final Rectangle   rightBorderArea;
057    
058         private final Rectangle   carBounds;
059    
060         //
061    
062         private TilePainter   tilePainter;
063    
064         private TileAnimator  tileAnimator;
065    
066         private RunnerSprite  runnerSprite;
067    
068         private EnemySprite   enemySprite;
069    
070         private boolean       componentResized;
071    
072         private Timekeeper    timekeeper;
073    
074         //////////////////////////////////////////////////////////////////////
075         //////////////////////////////////////////////////////////////////////
076    
077         public static void  main ( String [ ]  args )
078         //////////////////////////////////////////////////////////////////////
079         {
080           launch ( new Main ( ) );
081         }
082    
083         private static AnimationInit  createAnimationInit ( )
084         //////////////////////////////////////////////////////////////////////
085         {
086           AnimationInit  animationInit = new AnimationInit ( );
087    
088           animationInit.setAppletInfo ( APPLET_INFO );
089    
090           animationInit.setBackgroundColor ( BACKGROUND_COLOR );
091    
092           animationInit.setCursor ( CURSOR );
093    
094           animationInit.setFont ( FONT );
095    
096           animationInit.setForegroundColor ( FOREGROUND_COLOR );
097    
098           animationInit.setFrameIconFilename ( FRAME_ICON_FILENAME );
099    
100           animationInit.setFrameRate ( FRAME_RATE );
101    
102           animationInit.setFrameSize ( FRAME_SIZE );
103    
104           animationInit.setFrameTitle ( FRAME_TITLE );
105    
106           animationInit.setShutdownConfirmationPrompt (
107             SHUTDOWN_CONFIRMATION_PROMPT );
108    
109           return animationInit;
110         }
111    
112         //////////////////////////////////////////////////////////////////////
113         //////////////////////////////////////////////////////////////////////
114    
115         public  Main ( )
116         //////////////////////////////////////////////////////////////////////
117         {
118           super ( createAnimationInit ( ) );
119    
120           componentBounds  = new Rectangle ( );
121    
122           tileArea         = new Rectangle ( );
123    
124           leftBorderArea   = new Rectangle ( );
125    
126           rightBorderArea  = new Rectangle ( );
127    
128           carBounds        = new Rectangle ( );
129    
130           tileArea.width   = TILE_AREA_WIDTH;
131    
132           componentResized = true;
133         }
134    
135         //////////////////////////////////////////////////////////////////////
136         //////////////////////////////////////////////////////////////////////
137    
138         public void  init ( )
139         //////////////////////////////////////////////////////////////////////
140         {
141           super.init ( );
142    
143           // create left and right border painters
144    
145           addComponentPainter (
146             new ColorPainter ( BACKGROUND_COLOR, leftBorderArea ) );
147    
148           addComponentPainter (
149             new ColorPainter ( BACKGROUND_COLOR, rightBorderArea ) );
150    
151           // initialize background tiles
152    
153           Icon [ ]  tileIcons = new Icon [ TILE_IMAGE_FILENAMES.length ];
154    
155           for ( int  i = 0; i < tileIcons.length; i++ )
156           {
157             try
158             {
159               tileIcons [ i ] = new ImageIcon (
160                 ImageLib.loadAutomaticImage (
161                   MEDIA_DIR + TILE_IMAGE_FILENAMES [ i ]
162                     + IMAGE_FILENAME_EXTENSION,
163                   Transparency.OPAQUE,
164                   animatedComponent,
165                   getClass ( ).getClassLoader ( ),
166                   TILE_DIMENSION ) ); // dimension
167             }
168             catch ( Exception  ex )
169             {
170               tileIcons [ i ]
171                 = new ColorTileIcon ( Color.RED, TILE_DIMENSION );
172    
173               ex.printStackTrace ( );
174             }
175           }
176    
177           // initialize tileMap
178    
179           byte [ ] [ ]  tileMap = new byte [ ] [ ] { {
180             TILE_TYPE_WALL,
181             TILE_TYPE_GRASS,
182             TILE_TYPE_SHOULDER,
183             TILE_TYPE_ROAD,
184             TILE_TYPE_DIVIDER,
185             TILE_TYPE_ROAD,
186             TILE_TYPE_DIVIDER,
187             TILE_TYPE_ROAD,
188             TILE_TYPE_DIVIDER,
189             TILE_TYPE_ROAD,
190             TILE_TYPE_DIVIDER,
191             TILE_TYPE_ROAD,
192             TILE_TYPE_SHOULDER,
193             TILE_TYPE_GRASS,
194             TILE_TYPE_WALL } };
195    
196           // initialize TileAnimator
197    
198           tilePainter = new TilePainter (
199             0, // tileOffsetX
200             0, // tileOffsetY
201             tileIcons,
202             tileMap,
203             TILE_DIMENSION,
204             tileArea ); // tileShape
205    
206           tileAnimator = new TileAnimator ( tilePainter, 0, ROAD_RATE );
207    
208           addComponentAnimator ( tileAnimator );
209    
210           // initialize avatar
211    
212           Icon  runnerIcon = null;
213    
214           try
215           {
216             runnerIcon = new ImageIcon (
217               ImageLib.loadAutomaticImage (
218                 MEDIA_DIR + RUNNER_IMAGE_FILENAME + IMAGE_FILENAME_EXTENSION,
219                 Transparency.BITMASK, // transparent background
220                 animatedComponent,
221                 getClass ( ).getClassLoader ( ),
222                 TILE_DIMENSION ) );
223           }
224           catch ( Exception  ex )
225           {
226             runnerIcon = new ColorTileIcon ( Color.RED, TILE_DIMENSION );
227    
228             ex.printStackTrace ( );
229           }
230    
231           Car  car = new SeriCar ( new SeriModelId ( 0 ), carBounds );
232    
233           timekeeper
234             = new Timekeeper ( new HiResClock ( ), 1.0 );
235    
236           runnerSprite = new RunnerSprite (
237             car, runnerIcon, timekeeper, animatedComponent );
238    
239           addComponentAnimator ( runnerSprite );
240    
241           // initialize enemies
242    
243           Icon  enemyIcon = null;
244    
245           try
246           {
247             enemyIcon = new ImageIcon (
248               ImageLib.loadAutomaticImage (
249                 MEDIA_DIR + ENEMY_IMAGE_FILENAME + IMAGE_FILENAME_EXTENSION,
250                 Transparency.BITMASK, // transparent background
251                 animatedComponent,
252                 getClass ( ).getClassLoader ( ),
253                 TILE_DIMENSION ) );
254           }
255           catch ( Exception  ex )
256           {
257             enemyIcon = new ColorTileIcon ( Color.RED, TILE_DIMENSION );
258    
259             ex.printStackTrace ( );
260           }
261    
262           Car  enemyCar = new SeriCar ( new SeriModelId ( 1 ), carBounds );
263    
264           enemySprite = new EnemySprite (
265             enemyIcon, enemyCar, timekeeper, new Random ( ) );
266    
267           addComponentAnimator ( enemySprite );
268    
269           // The frame rate display is toggled when the 'f' key is pressed.
270    
271           addComponentAnimator (
272             new FrameRateController ( animatedComponent )
273               .getFrameRateAnimator ( ) );
274           //
275    
276           animatedComponent.addComponentListener (
277             new ComponentAdapter ( )
278             {
279               public void  componentResized ( ComponentEvent  componentEvent )
280               {
281                 componentResized = true;
282               }
283             } );
284         }
285    
286         //////////////////////////////////////////////////////////////////////
287         //////////////////////////////////////////////////////////////////////
288    
289         public void  update ( JComponent  component )
290         //////////////////////////////////////////////////////////////////////
291         {
292           if ( componentResized )
293           {
294             resetBounds ( );
295    
296             component.repaint ( );
297    
298             componentResized = false;
299           }
300    
301           timekeeper.update ( );
302    
303           super.update ( component );
304         }
305    
306         //////////////////////////////////////////////////////////////////////
307         //////////////////////////////////////////////////////////////////////
308    
309         private void  resetBounds ( )
310         //////////////////////////////////////////////////////////////////////
311         {
312           animatedComponent.getBounds ( componentBounds );
313    
314           tileArea.x = ( componentBounds.width - TILE_AREA_WIDTH ) / 2;
315    
316           tilePainter.setOffsetX ( tileArea.x );
317    
318           tileArea.height = componentBounds.height;
319    
320           leftBorderArea.width = tileArea.x > 0 ? tileArea.x : 0;
321    
322           leftBorderArea.height = componentBounds.height;
323    
324           rightBorderArea.x = tileArea.x + TILE_AREA_WIDTH;
325    
326           int  rightBorderWidth = componentBounds.width - rightBorderArea.x;
327    
328           rightBorderArea.width = rightBorderWidth > 0 ? rightBorderWidth : 0;
329    
330           rightBorderArea.height = componentBounds.height;
331    
332           carBounds.x = tileArea.x + TILE_SIZE;
333    
334           carBounds.width = rightBorderArea.x - 2 * TILE_SIZE - carBounds.x;
335    
336           carBounds.height = componentBounds.height;
337         }
338    
339         //////////////////////////////////////////////////////////////////////
340         //////////////////////////////////////////////////////////////////////
341         }