1 package se
.umu
.cs
.dit06ajnajs
.agent
;
4 import java
.awt
.Graphics
;
7 import java
.util
.ArrayList
;
9 import java
.util
.Observable
;
10 import java
.util
.Observer
;
11 import java
.util
.logging
.Logger
;
12 import java
.awt
.Rectangle
;
15 * Abstract class used as superclass to all Towers in a game. All methods are
16 * implemented and can be used as a basic Tower.
18 * @author Anton Johansson (dit06ajn@cs.umu.se)
19 * @author Andreas Jakobsson (dit06ajs@cs.umu.se)
22 public abstract class Tower
implements Agent
, Observer
{
24 private static Logger logger
= Logger
.getLogger("AntiTD");
37 private boolean alive
;
38 private boolean fiering
;
39 private List
<Unit
> fireingList
;
42 * Sets basic parameters needed for a Tower, sets the Tower to be alive and
45 * @param width The width of this Tower.
46 * @param height The height of this Tower.
47 * @param damage The amount of damage this Tower gives each time it fires.
48 * @param range The range of this Tower given as a radius of pixels around
50 * @param image The Image that this tower draws when its paint() method is
53 public Tower(int width
, int height
, int damage
, int range
, Image image
) {
65 * Used to initialize fields that should not be individually set for every
66 * Tower, since clone() is shallow.
69 this.fireingList
= new ArrayList
<Unit
>();
73 * Set the image used by this Tower.
75 * @param image A new Image.
77 public void setImage(Image image
) {
82 * Sets the position of this Tower.
84 * @param point The new point of this Tower.
86 public void setPostition(Point point
) {
89 this.centerX
= this.x
+ (this.width
/2);
90 this.centerY
= this.y
+ (this.height
/2);
94 * Get the range of this Thower.
96 * @return The range of this Tower.
98 public int getRange() {
103 * Called when this Tower acts. If it's fireing list is not empty it fires
104 * on Units that are in range and removes Units that are out of range.
107 if (!fireingList
.isEmpty()) {
108 Unit unit
= fireingList
.get(0);
109 if (unit
.isAlive()) {
110 Point unitPoint
= unit
.getCenterPoint();
112 int unitXPos
= unitPoint
.x
;
113 int unitYPos
= unitPoint
.y
;
114 int distans
= (int) Math
.hypot((this.centerX
- unitXPos
),
115 this.centerY
- unitYPos
);
116 logger
.fine("Tower range: " + this.range
);
117 logger
.fine("Distance to unit: " + distans
);
118 if (distans
< this.range
) {
119 logger
.fine("UNIT IN RANGE, FIIIIIREEEEEEE!!!");
123 logger
.info("Unit out of reach, removing from fireingList");
124 fireingList
.remove(unit
);
127 logger
.info("Unit is dead, removing from fireingList");
128 fireingList
.remove(unit
);
134 * Towers are added to PathSquares in their fireingrage, when Units landOn()
135 * those squares this method is called. Units from argument to this method
136 * are added to firering list.
138 * @param caller The caller of this method.
139 * @param arg Should always be the Unit traversing over a PathSquares in
140 * range from this Tower.
142 public void update(Observable caller
, Object arg
) {
143 // Should always be units
144 if (arg
instanceof Unit
) {
145 Unit unit
= (Unit
) arg
;
146 if (!fireingList
.contains(unit
)) {
147 fireingList
.add(unit
);
148 logger
.info("Unit >" + unit
.getClass().getSimpleName() +
149 "< added to tower...");
155 * Returns the state of this Tower, dead or alive.
157 * @return true if this Tower is alive, false otherwise.
159 public boolean isAlive() {
164 * Sets this Tower alive status.
166 * @param state false if Tower should be killed, true if it should live.
168 public void setAlive(boolean state
) {
172 /** Used to calculate and set a new x-center after x is changed. */
173 private void recalculateCenterX() {
174 this.centerX
= this.x
+ this.width
/ 2;
177 /** Used to calculate and set a new y-center after y is changed. */
178 private void recalculateCenterY() {
179 this.centerY
= this.y
+ this.height
/ 2;
183 * Sets the current height, recalculates and sets a new centerY value.
185 * @param height The new height value.
187 public void setHeight(int height
) {
188 this.height
= height
;
189 recalculateCenterY();
193 * Returns the height of this Tower.
195 * @return The height of this Tower.
197 public int getHeight() {
202 * Returns the width of this Tower.
204 * @return The width of this Tower.
206 public int getWidth() {
211 * Sets the width, recalculates and sets a new centerX value.
213 * @param width The new width value.
215 public void setWidth(int width
) {
217 recalculateCenterX();
221 * Returns the x-position of this Tower.
223 * @return The x-position of this Tower.
230 * Returns the y-position of this Tower.
232 * @return The y-position of this Tower.
239 * Returns the x-center point of this Tower.
241 * @return The x-center point of this Tower.
243 public int getCenterX() {
248 * Returns the y-center point of this Tower.
250 * @return The y-center point of this Tower.
252 public int getCenterY() {
257 * Get the center point of this Tower.
259 * @return The center point of this Tower.
261 public Point
getCenterPoint() {
262 return new Point(this.centerX
, this.centerY
);
266 * Returns the state of this Towers fireing.
268 * @return true if this Tower fires, false otherwise.
270 private boolean isFiering() {
275 * Set the fire state of this Tower.
277 * @param fiering true if the Tower is fireing, false otherwise.
279 private void setFiering(boolean fiering
) {
280 this.fiering
= fiering
;
284 * Returns a list of Units this Tower has in its fireing list.
286 * @return A list of Units this Tower has in its fireing list.
288 public List
<Unit
> getFireingList() {
289 return this.fireingList
;
295 * @param g The Graphics to paint to.
297 public void paint(Graphics g
) {
298 g
.drawImage(image
, x
, y
, null);
300 // Draw a line to the Unit this Tower fires on.
301 if (this.isFiering()) {
302 this.setFiering(false);
303 g
.setColor(Color
.WHITE
);
304 List
<Unit
> fireingList
= this.getFireingList();
305 if (!fireingList
.isEmpty()) {
306 Unit unit
= this.getFireingList().get(0);
307 g
.drawLine(this.getCenterX(), this.getCenterY(),
308 unit
.getCenterPoint().x
, unit
.getCenterPoint().y
);
314 * Empty method to handle mouseClicks, override in subclass to implement
317 public void click() {
318 // Override in subclass to implement behaviour.
322 * Checks if the specified x and y position is inside of this Towers bounds.
324 * @param x The x-value to check.
325 * @param y The y-value to check.
326 * @return If the specified x and y position is inside of this Towers bounds.
328 public boolean contains(int x
, int y
) {
329 return new Rectangle(this.x
, this.y
, width
, height
).contains(x
, y
);
333 * Attemts to clone this Tower.
335 * @return A new instance of the same type as the instantiated Tower.
338 public Object
clone() {
340 return super.clone();
341 } catch (CloneNotSupportedException e
) {
343 throw new Error("Object " + this.getClass().getName()
344 + " is not Cloneable");