001         package com.croftsoft.apps.sprite;
002    
003         import java.awt.Rectangle;
004         import javax.swing.Icon;
005         import javax.swing.JComponent;
006    
007         import com.croftsoft.core.animation.Clock;
008         import com.croftsoft.core.animation.ComponentUpdater;
009         import com.croftsoft.core.animation.sprite.IconSprite;
010         import com.croftsoft.core.lang.NullArgumentException;
011    
012         /*********************************************************************
013         * Switches the Sprite Icon based upon heading changes.
014         *
015         * @version
016         *   2002-03-23
017         * @since
018         *   2002-02-24
019         * @author
020         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
021         *********************************************************************/
022    
023         public final class  ImpactUpdater
024           implements ComponentUpdater
025         //////////////////////////////////////////////////////////////////////
026         //////////////////////////////////////////////////////////////////////
027         {
028    
029         private final IconSprite  iconSprite;
030    
031         private final Icon        normalIcon;
032    
033         private final Icon        impactIcon;
034    
035         private final long        impactDuration;
036    
037         private final Clock       clock;
038    
039         private final Rectangle   repaintRegion;
040    
041         //
042    
043         private double   oldHeading;
044    
045         private long     lastImpactTime;
046    
047         private boolean  isImpacted;
048    
049         private Icon     icon;
050    
051         //////////////////////////////////////////////////////////////////////
052         //////////////////////////////////////////////////////////////////////
053    
054         public  ImpactUpdater (
055           IconSprite  iconSprite,
056           Icon        normalIcon,
057           Icon        impactIcon,
058           long        impactDuration,
059           Clock       clock )
060         //////////////////////////////////////////////////////////////////////
061         {
062           NullArgumentException.check ( this.iconSprite = iconSprite );
063    
064           NullArgumentException.check ( this.normalIcon = normalIcon );
065    
066           NullArgumentException.check ( this.impactIcon = impactIcon );
067    
068           this.impactDuration = impactDuration;
069    
070           NullArgumentException.check ( this.clock      = clock      );
071    
072           repaintRegion = new Rectangle ( );
073         }
074    
075         //////////////////////////////////////////////////////////////////////
076         //////////////////////////////////////////////////////////////////////
077    
078         public void  update ( JComponent  component )
079         //////////////////////////////////////////////////////////////////////
080         {
081           long  updateTimeNanos = clock.currentTimeNanos ( );
082    
083           if ( iconSprite.getHeading ( ) != oldHeading )
084           {
085             oldHeading = iconSprite.getHeading ( );
086    
087             icon = impactIcon;
088    
089             lastImpactTime = updateTimeNanos;
090    
091             isImpacted = true;
092           }
093           else if ( isImpacted
094             && ( updateTimeNanos >= lastImpactTime + impactDuration ) )
095           {
096             icon = normalIcon;
097    
098             isImpacted = false;
099           }
100           else
101           {
102             return;
103           }
104    
105           if ( icon == iconSprite.getIcon ( ) )
106           {
107             return;
108           }
109    
110           iconSprite.getPaintBounds ( repaintRegion );
111    
112           component.repaint ( repaintRegion );
113    
114           iconSprite.setIcon ( icon );
115    
116           iconSprite.getPaintBounds ( repaintRegion );
117    
118           component.repaint ( repaintRegion );
119         }
120    
121         //////////////////////////////////////////////////////////////////////
122         //////////////////////////////////////////////////////////////////////
123         }