Changed package name map to level
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / agent / Unit.java
blob7180f7a87ae0d90a77fea671b4e0ad1bad68b404
1 package se.umu.cs.dit06ajnajs.agent;
3 import java.applet.AudioClip;
4 import java.awt.Graphics;
5 import java.awt.Image;
6 import java.awt.Point;
7 import java.util.Map;
8 import java.util.logging.Logger;
10 import se.umu.cs.dit06ajnajs.ATDSoundPlayer;
11 import se.umu.cs.dit06ajnajs.level.Level;
12 import se.umu.cs.dit06ajnajs.level.MapSquare;
13 import se.umu.cs.dit06ajnajs.level.Traversable;
15 import java.awt.Rectangle;
16 import java.awt.Color;
18 // TODO: write a testclass to test all get- set-positions with center top left..
19 public abstract class Unit implements Agent {
20 private static Logger logger = Logger.getLogger("AntiTD");
22 private int x;
23 private int y;
24 private int centerX;
25 private int centerY;
27 private int width;
28 private int height;
30 private String type;
31 private int speed;
32 private int health;
33 private int currentHealth;
34 private int cost;
36 private Map<Direction, Image> images;
37 private Map<String, AudioClip> sounds;
38 private Direction direction;
39 private Level level;
40 private boolean alive;
41 private boolean pause;
42 private Object lastTurnedBy;
44 public Unit(String type, int width, int height, int speed, int health,
45 int cost, Map<Direction, Image> images,
46 Map<String, AudioClip> sounds) {
47 this.type = type;
48 this.width = width;
49 this.height = height;
50 setX(x);
51 setY(y);
52 this.speed = speed;
53 this.health = health;
54 this.currentHealth = health;
55 this.cost = cost;
56 this.images = images;
57 this.sounds = sounds;
59 this.alive = true;
60 this.pause = false;
63 public void setImage(Image img) {
64 // TODO Auto-generated method stub
67 public String getType() {
68 return this.type;
71 // TODO används denna?
72 public Map<Direction, Image> getImages() {
73 return this.images;
76 public void act() {
77 // Check if this unit has health left
78 if (this.currentHealth > 0) {
79 // Check if this unit is active
80 if (!pause) {
81 Point nextPos = getNextPosition();
82 // TODO check for collision on next position
83 move(nextPos);
85 // Land on current square
86 MapSquare currentSquare = level.getMapSquareAtPoint(centerX, centerY);
87 if (currentSquare instanceof Traversable) {
88 ((Traversable) currentSquare).landOn(this);
89 } else {
90 // Unit hitting something not Traversable and therefor dies.
91 this.alive = false;
93 } else {
94 // Toggle pause back to false;
95 pause = false;
97 } else {
98 // Kill unit
99 this.alive = false;
100 ATDSoundPlayer.play(sounds.get("dead"));
104 public Point getNextPosition() {
105 switch (direction) {
106 case UP:
107 logger.fine("UP");
108 return new Point(x, y - speed);
109 case DOWN:
110 logger.fine("DOWN");
111 return new Point(x, y + speed);
112 case LEFT:
113 logger.fine("LEFT");
114 return new Point(x - speed, y);
115 case RIGHT:
116 logger.fine("RIGHT");
117 return new Point(x + speed, y);
118 default:
119 System.err.println("Unit has not got a valid Direction");
120 return null;
124 public void move(Point p) {
125 setX(p.x);
126 setY(p.y);
129 public int getX() {
130 return x;
133 public void setX(int x) {
134 this.x = x;
135 recalculateCenterX();
138 public int getY() {
139 return y;
142 public void setY(int y) {
143 this.y = y;
144 recalculateCenterY();
147 public void setWidth(int width) {
148 this.width = width;
149 recalculateCenterX();
152 public void setHeight(int height) {
153 this.height = height;
154 recalculateCenterY();
157 public void setCenterX(int centerX) {
158 this.centerX = centerX;
159 setX(centerX - (width / 2));
162 public void setCenterY(int centerY) {
163 this.centerY = centerY;
164 setY(centerY - (width / 2));
167 public void setCenterPoint(int centerX, int centerY) {
168 setCenterPoint(new Point(centerX, centerY));
171 public void setCenterPoint(Point point) {
172 setCenterX(point.x);
173 setCenterY(point.y);
176 public Point getCenterPoint() {
177 return new Point(this.centerX, this.centerY);
180 public int getWidth() {
181 return width;
184 public int getHeight() {
185 return height;
188 public int getSpeed() {
189 return speed;
192 public void setSpeed(int speed) {
193 this.speed = speed;
196 public int getCost() {
197 return this.cost;
200 public Direction getDirection() {
201 return direction;
204 public void setDirection(Direction direction, Object caller) {
205 if (this.lastTurnedBy != caller) {
206 this.direction = direction;
207 this.lastTurnedBy = caller;
208 } else {
209 System.err.println("Turned by same caller twice: " + caller);
213 public void setMap(Level level) {
214 this.level = level;
217 public boolean isAlive() {
218 return this.alive;
221 public void setAlive(boolean state) {
222 this.alive = state;
225 /** Used to calculate and set a new x-center after x is changed. */
226 private void recalculateCenterX() {
227 this.centerX = this.x + this.width / 2;
230 /** Used to calculate and set a new y-center after y is changed. */
231 private void recalculateCenterY() {
232 this.centerY = this.y + this.height / 2;
236 * Decrease the units currentHealth.
237 * @param damage The number of health points to substract
239 public void damage(int damage) {
240 this.currentHealth -= damage;
244 * Attemts to clone this Unit.
246 * @return A new instance of the same type as the instantiated Unit.
248 @Override
249 public Object clone() {
250 try {
251 return super.clone();
252 } catch (CloneNotSupportedException e) {
253 e.printStackTrace();
254 throw new Error("Object " + this.getClass().getName()
255 + " is not Cloneable");
259 public void collision(Unit unit) {
260 switch (direction) {
261 case UP:
262 if (unit.getDirection() == Direction.DOWN) {
263 setDirection(Direction.DOWN, unit);
264 unit.setDirection(Direction.UP, this);
265 return;
267 break;
268 case DOWN:
269 if (unit.getDirection() == Direction.UP) {
270 setDirection(Direction.UP, unit);
271 unit.setDirection(Direction.DOWN, this);
272 return;
274 break;
275 case LEFT:
276 if (unit.getDirection() == Direction.RIGHT) {
277 setDirection(Direction.RIGHT, unit);
278 unit.setDirection(Direction.LEFT, this);
279 return;
281 break;
282 case RIGHT:
283 if (unit.getDirection() == Direction.LEFT) {
284 setDirection(Direction.LEFT, unit);
285 unit.setDirection(Direction.RIGHT, this);
286 return;
288 break;
289 default:
290 System.err.println("Unit hasn't got a valid Direction");
291 break;
293 this.pause = true;
296 public boolean isPaused() {
297 return this.pause;
300 @Override
301 public String toString() {
302 return getType() + ", cost: " + getCost() + ", strenght: " + this.health;
306 * Empty method to handle mouseClicks, override in subclass to implement
307 * behaviour.
310 public void click() {
311 // Overried in subclass
312 logger.info("Unit clicked " + this.toString());
313 ATDSoundPlayer.play(sounds.get("onClick"));
317 * Checks if the specified x and y position is inside of this Units bounds.
319 * @param x The x-value to check.
320 * @param y The y-value to check.
321 * @return If the specified x and y position is inside of this Units bounds.
323 public boolean contains(int x, int y) {
324 return new Rectangle(x, y, width, health).contains(x, y);
327 public Rectangle getBounds() {
328 return new Rectangle(x, y, width, height);
331 public Rectangle getFutureBounds() {
332 Point nextPoint = getNextPosition();
333 return new Rectangle(nextPoint.x, nextPoint.y, width, height);
336 public boolean intersects(Unit unit) {
337 return this.getBounds().intersects(unit.getBounds());
340 public boolean intersectsNextMove(Unit unit) {
341 return this.getFutureBounds().intersects(unit.getBounds());
344 public void paint(Graphics g) {
345 Image image = images.get(direction);
346 g.drawImage(image, x, y, null);
348 int healthHeight = 2;
349 int yHealth = y + height - healthHeight;
350 g.setColor(Color.RED);
351 g.fillRect(x , yHealth, width, healthHeight);
352 g.setColor(Color.GREEN);
353 int healthBar = (int) (width * (new Double(currentHealth) / health));
354 g.fillRect(x , yHealth, healthBar, healthHeight);