Report, linebreak
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / agent / Tower.java
blobc7d623b39d92d13ac59730a7bd63734dd0450319
1 package se.umu.cs.dit06ajnajs.agent;
3 import java.awt.Color;
4 import java.awt.Graphics;
5 import java.awt.Image;
6 import java.awt.Point;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.util.Observable;
10 import java.util.Observer;
11 import java.util.logging.Logger;
12 import java.awt.Rectangle;
14 /**
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)
20 * @version 1.0
22 public abstract class Tower implements Agent, Observer {
24 private static Logger logger = Logger.getLogger("AntiTD");
26 private int x;
27 private int y;
28 private int centerX;
29 private int centerY;
31 private int width;
32 private int height;
34 private int damage;
35 private int range;
36 private Image image;
37 private boolean alive;
38 private boolean fiering;
39 private List<Unit> fireingList;
41 /**
42 * Sets basic parameters needed for a Tower, sets the Tower to be alive and
43 * not fiering.
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
49 * the tower.
50 * @param image The Image that this tower draws when its paint() method is
51 * called.
53 public Tower(int width, int height, int damage, int range, Image image) {
54 this.width = width;
55 this.height = height;
56 this.damage = damage;
57 this.range = range;
58 this.image = image;
60 this.alive = true;
61 this.fiering = false;
64 /**
65 * Used to initialize fields that should not be individually set for every
66 * Tower, since clone() is shallow.
68 public void init() {
69 this.fireingList = new ArrayList<Unit>();
72 /**
73 * Set the image used by this Tower.
75 * @param image A new Image.
77 public void setImage(Image image) {
78 this.image = image;
81 /**
82 * Sets the position of this Tower.
84 * @param point The new point of this Tower.
86 public void setPostition(Point point) {
87 this.x = point.x;
88 this.y = point.y;
89 this.centerX = this.x + (this.width/2);
90 this.centerY = this.y + (this.height/2);
93 /**
94 * Get the range of this Thower.
96 * @return The range of this Tower.
98 public int getRange() {
99 return this.range;
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.
106 public void act() {
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!!!");
120 this.fiering = true;
121 unit.damage(damage);
122 } else {
123 logger.info("Unit out of reach, removing from fireingList");
124 fireingList.remove(unit);
126 } else {
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() {
160 return this.alive;
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) {
169 this.alive = 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() {
198 return height;
202 * Returns the width of this Tower.
204 * @return The width of this Tower.
206 public int getWidth() {
207 return width;
211 * Sets the width, recalculates and sets a new centerX value.
213 * @param width The new width value.
215 public void setWidth(int width) {
216 this.width = width;
217 recalculateCenterX();
221 * Returns the x-position of this Tower.
223 * @return The x-position of this Tower.
225 public int getX() {
226 return this.x;
230 * Returns the y-position of this Tower.
232 * @return The y-position of this Tower.
234 public int getY() {
235 return this.y;
239 * Returns the x-center point of this Tower.
241 * @return The x-center point of this Tower.
243 public int getCenterX() {
244 return centerX;
248 * Returns the y-center point of this Tower.
250 * @return The y-center point of this Tower.
252 public int getCenterY() {
253 return centerY;
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() {
271 return this.fiering;
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;
293 * Paints this Tower.
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
315 * behaviour.
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.
337 @Override
338 public Object clone() {
339 try {
340 return super.clone();
341 } catch (CloneNotSupportedException e) {
342 e.printStackTrace();
343 throw new Error("Object " + this.getClass().getName()
344 + " is not Cloneable");