001         package com.croftsoft.apps.mars.model.seri;
002    
003         import java.awt.Shape;
004    
005         import com.croftsoft.core.lang.NullArgumentException;
006         import com.croftsoft.core.math.geom.Circle;
007         import com.croftsoft.core.math.geom.PointXY;
008         import com.croftsoft.core.util.ArrayKeeper;
009    
010         import com.croftsoft.apps.mars.model.Bullet;
011         import com.croftsoft.apps.mars.model.Damageable;
012         import com.croftsoft.apps.mars.model.Impassable;
013         import com.croftsoft.apps.mars.model.Model;
014         import com.croftsoft.apps.mars.model.World;
015    
016         /*********************************************************************
017         * A bullet.
018         *
019         * @version
020         *   2003-04-15
021         * @since
022         *   2003-04-01
023         * @author
024         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
025         *********************************************************************/
026    
027         public final class  SeriBullet
028           extends SeriModel
029           implements Bullet
030         //////////////////////////////////////////////////////////////////////
031         //////////////////////////////////////////////////////////////////////
032         {
033    
034         private static final long  serialVersionUID = 0L;
035    
036         //
037    
038         private static final Class [ ]  TARGET_CLASSES
039           = new Class [ ] { Damageable.class, Impassable.class };
040    
041         private static final double  DAMAGE   = 1.0;
042    
043         private static final double  VELOCITY = 90.0;
044    
045         private static final double  RADIUS =   3.0;
046    
047         private static final double  RANGE  = 200.0;
048    
049         private static final double  Z      =   2.0;
050    
051         //
052    
053         private final World   world;
054    
055         private final Circle  circle;
056    
057         //
058    
059         private boolean  active;
060    
061         private double   distance;
062    
063         private double   heading;
064    
065         private double   originX;
066    
067         private double   originY;
068    
069         private boolean  updated;
070    
071         //////////////////////////////////////////////////////////////////////
072         //////////////////////////////////////////////////////////////////////
073    
074         public  SeriBullet (
075           World   world,
076           double  originX,
077           double  originY,
078           double  heading )
079         //////////////////////////////////////////////////////////////////////
080         {
081           NullArgumentException.check ( this.world = world );
082    
083           circle = new Circle ( 0.0, 0.0, RADIUS );
084    
085           fire ( originX, originY, heading );
086         }
087    
088         //////////////////////////////////////////////////////////////////////
089         // interface Model methods
090         //////////////////////////////////////////////////////////////////////
091    
092         public boolean  isActive  ( ) { return active;  }
093    
094         public Shape    getShape  ( ) { return circle;  }
095    
096         public boolean  isUpdated ( ) { return updated; }
097    
098         public double   getZ      ( ) { return Z;       }
099    
100         public void  prepare ( )
101         //////////////////////////////////////////////////////////////////////
102         {
103           updated = false;
104         }
105    
106         public void  update ( double  timeDelta )
107         //////////////////////////////////////////////////////////////////////
108         {
109           if ( !active )
110           {
111             return;
112           }
113    
114           updated = true;
115    
116           distance += timeDelta * VELOCITY;
117    
118           if ( ( distance > RANGE )
119             || ( distance < 0.0   ) )
120           {
121             active = false;
122    
123             return;
124           }
125    
126           circle.setCenter (
127             originX + distance * Math.cos ( heading ),
128             originY + distance * Math.sin ( heading ) );
129    
130           PointXY  center = circle.getCenter ( );
131    
132           Model  model
133             = world.getModel ( circle.getCenter ( ), TARGET_CLASSES, this );
134    
135           if ( model != null )
136           {
137             active = false;
138    
139             if ( model instanceof Damageable )
140             {
141               ( ( Damageable ) model ).addDamage ( DAMAGE );
142             }
143           }
144         }
145    
146         //////////////////////////////////////////////////////////////////////
147         //////////////////////////////////////////////////////////////////////
148    
149         public void  fire (
150           double  originX,
151           double  originY,
152           double  heading )
153         //////////////////////////////////////////////////////////////////////
154         {
155           this.originX = originX;
156    
157           this.originY = originY;
158    
159           this.heading = heading;
160    
161           distance     = 0.0;
162    
163           active       = true;
164    
165           updated      = true;
166    
167           circle.setCenter ( originX, originY );
168         }
169    
170         public void  setCenter (
171           double  x,
172           double  y )
173         //////////////////////////////////////////////////////////////////////
174         {
175           circle.setCenter ( x, y );       
176         }
177    
178         //////////////////////////////////////////////////////////////////////
179         //////////////////////////////////////////////////////////////////////
180         }