001         package com.croftsoft.apps.sprite;
002    
003         import java.awt.Color;
004         import java.awt.Rectangle;
005         import java.util.Random;
006         import javax.swing.JComponent;
007    
008         import com.croftsoft.core.animation.Clock;
009         import com.croftsoft.core.animation.ComponentUpdater;
010         import com.croftsoft.core.animation.painter.ColorPainter;
011         import com.croftsoft.core.lang.NullArgumentException;
012    
013         /*********************************************************************
014         * Updates scene shading for fog and night and changes brick color.
015         *
016         * @version
017         *   2002-12-05
018         * @since
019         *   2002-02-20
020         * @author
021         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
022         *********************************************************************/
023    
024         public final class  FogNightUpdater
025           implements ComponentUpdater
026         //////////////////////////////////////////////////////////////////////
027         //////////////////////////////////////////////////////////////////////
028         {
029    
030         private static final long  NANOSECONDS_PER_SECOND = 1000000000L;
031    
032         private final ColorPainter  fogNightPainter;
033    
034         private final ColorPainter  brickColorPainter;
035    
036         private final long          fullCyclePeriodNanos;
037    
038         private final Clock         clock;
039    
040         private final Color [ ]     fogColors;
041    
042         private final Color [ ]     nightColors;
043    
044         private final Random        brickColorRandom;
045    
046         //
047    
048         private long  offsetTime;
049    
050         private int   oldIndex;
051    
052         //////////////////////////////////////////////////////////////////////
053         //////////////////////////////////////////////////////////////////////
054    
055         public  FogNightUpdater (
056           ColorPainter  fogNightPainter,
057           ColorPainter  brickColorPainter,
058           int           fullCyclePeriod,
059           Clock         clock )
060         //////////////////////////////////////////////////////////////////////
061         {
062           NullArgumentException.check (
063             this.fogNightPainter = fogNightPainter );
064    
065           NullArgumentException.check (
066             this.brickColorPainter = brickColorPainter );
067    
068           if ( fullCyclePeriod < 1 )
069           {
070             throw new IllegalArgumentException ( "fullCyclePeriod < 1" );
071           }
072    
073           NullArgumentException.check ( this.clock = clock );
074    
075           this.fullCyclePeriodNanos
076             = NANOSECONDS_PER_SECOND * fullCyclePeriod;
077    
078           nightColors = new Color [ 256 ];
079    
080           fogColors   = new Color [ 256 ];
081    
082           for ( int  alpha = 0; alpha < 256; alpha++ )
083           {
084             nightColors [ alpha ] = new Color (   0,   0,   0, alpha );
085    
086             fogColors   [ alpha ] = new Color ( 255, 255, 255, alpha );
087           }
088    
089           brickColorRandom = new Random ( );
090    
091           oldIndex = -1; // out of range, force an immediate Color update
092    
093           reset ( );
094         }
095    
096         //////////////////////////////////////////////////////////////////////
097         //////////////////////////////////////////////////////////////////////
098    
099         public void  reset ( )
100         //////////////////////////////////////////////////////////////////////
101         {
102           offsetTime = -1;
103         }
104    
105         public void  update ( JComponent  component )
106         //////////////////////////////////////////////////////////////////////
107         {
108           long  updateTimeNanos = clock.currentTimeNanos ( );
109    
110           if ( offsetTime < 0 )
111           {
112             offsetTime = updateTimeNanos;
113           }
114    
115           int  index = ( int )
116             ( ( ( ( updateTimeNanos - offsetTime ) % fullCyclePeriodNanos )
117             * ( 256 * 6 ) ) / fullCyclePeriodNanos );
118    
119           if ( index == oldIndex )
120           {
121             return;
122           }
123    
124           if ( index < oldIndex )
125           {
126             brickColorPainter.setColor (
127               new Color (
128                 brickColorRandom.nextInt ( 256 ),
129                 brickColorRandom.nextInt ( 256 ),
130                 brickColorRandom.nextInt ( 256 ) ) );
131           }
132    
133           oldIndex = index;
134    
135           int  phase = index / 256;
136    
137           index = index % 256;
138    
139           Color  fogNightColor = null;
140    
141           if ( phase == 0 )
142           {
143             //  going from night to day
144    
145             fogNightColor = nightColors [ 255 - index ];
146           }
147           else if ( phase == 1 )
148           {
149             // day
150    
151             fogNightColor = nightColors [ 0 ];
152           }       
153           else if ( phase == 2 )
154           {
155             // going from day to fog
156    
157             fogNightColor = fogColors [ index ];
158           }
159           else if ( phase == 3 )
160           {
161             // going from fog to day
162    
163             fogNightColor = fogColors [ 255 - index ];
164           }
165           else if ( phase == 4 )
166           {
167             // day
168    
169             fogNightColor = fogColors [ 0 ];
170           }       
171           else if ( phase == 5 )
172           {
173             // going from day to night
174    
175             fogNightColor = nightColors [ index ];
176           }
177    
178           fogNightPainter.setColor ( fogNightColor );
179    
180           component.repaint ( );
181         }
182    
183         //////////////////////////////////////////////////////////////////////
184         //////////////////////////////////////////////////////////////////////
185         }