Seal! 'n' stuff
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / agent / Unit.java
blob37b445dbc7a8dc873da241cb07b992bb7c72ec49
1 package se.umu.cs.dit06ajnajs.agent;
3 import java.awt.Graphics;
4 import java.awt.Image;
5 import java.awt.Point;
6 import java.util.Map;
7 import java.util.logging.Logger;
9 import se.umu.cs.dit06ajnajs.Paintable;
10 import se.umu.cs.dit06ajnajs.map.Level;
11 import se.umu.cs.dit06ajnajs.map.MapSquare;
12 import se.umu.cs.dit06ajnajs.map.Traversable;
13 import java.awt.Rectangle;
14 import java.awt.Color;
15 import java.awt.geom.Area;
17 // TODO: write a testclass to test all get- set-positions with center top left..
18 public abstract class Unit implements Agent, Paintable, Cloneable {
19 private static Logger logger = Logger.getLogger("AntiTD");
21 private int x;
22 private int y;
23 private int centerX;
24 private int centerY;
26 private int width;
27 private int height;
29 private String type;
30 private int speed;
31 private int health;
32 private int currentHealth;
33 private int cost;
35 private Map<Direction, Image> images;
36 private Direction direction;
37 private Level level;
38 private boolean alive;
39 private boolean pause;
40 private Object lastTurnedBy;
42 public Unit(String type, int width, int height, int speed, int health,
43 int cost, Map<Direction, Image> images) {
44 this.type = type;
45 this.width = width;
46 this.height = height;
47 setX(x);
48 setY(y);
49 this.speed = speed;
50 this.health = health;
51 this.currentHealth = health;
52 this.cost = cost;
53 this.images = images;
55 this.alive = true;
56 this.pause = false;
59 public void setImage(Image img) {
60 // TODO Auto-generated method stub
63 public String getType() {
64 return this.type;
67 // TODO används denna?
68 public Map<Direction, Image> getImages() {
69 return this.images;
72 public void act() {
73 // Check if this unit has health left
74 if (this.currentHealth > 0) {
75 // Check if this unit is active
76 if (!pause) {
77 Point nextPos = getNextPosition();
78 // TODO check for collision on next position
79 move(nextPos);
81 // Land on current square
82 MapSquare currentSquare = level.getMapSquareAtPoint(centerX, centerY);
83 if (currentSquare instanceof Traversable) {
84 ((Traversable) currentSquare).landOn(this);
85 } else {
86 // Unit hitting something not Traversable and therefor dies.
87 this.alive = false;
89 } else {
90 // Toggle pause back to false;
91 pause = false;
93 } else {
94 // Kill unit
95 this.alive = false;
99 public Point getNextPosition() {
100 switch (direction) {
101 case UP:
102 logger.fine("UP");
103 return new Point(x, y - speed);
104 case DOWN:
105 logger.fine("DOWN");
106 return new Point(x, y + speed);
107 case LEFT:
108 logger.fine("LEFT");
109 return new Point(x - speed, y);
110 case RIGHT:
111 logger.fine("RIGHT");
112 return new Point(x + speed, y);
113 default:
114 System.err.println("Unit has not got a valid Direction");
115 return null;
119 public void move(Point p) {
120 setX(p.x);
121 setY(p.y);
124 public int getX() {
125 return x;
128 public void setX(int x) {
129 this.x = x;
130 recalculateCenterX();
133 public int getY() {
134 return y;
137 public void setY(int y) {
138 this.y = y;
139 recalculateCenterY();
142 public void setWidth(int width) {
143 this.width = width;
144 recalculateCenterX();
147 public void setHeight(int height) {
148 this.height = height;
149 recalculateCenterY();
152 public void setCenterX(int centerX) {
153 this.centerX = centerX;
154 setX(centerX - (width / 2));
157 public void setCenterY(int centerY) {
158 this.centerY = centerY;
159 setY(centerY - (width / 2));
162 public void setCenterPoint(int centerX, int centerY) {
163 setCenterPoint(new Point(centerX, centerY));
166 public void setCenterPoint(Point point) {
167 setCenterX(point.x);
168 setCenterY(point.y);
171 public Point getCenterPoint() {
172 return new Point(this.centerX, this.centerY);
175 public int getWidth() {
176 return width;
179 public int getHeight() {
180 return height;
183 public int getSpeed() {
184 return speed;
187 public void setSpeed(int speed) {
188 this.speed = speed;
191 public int getCost() {
192 return this.cost;
195 public Direction getDirection() {
196 return direction;
199 public void setDirection(Direction direction, Object caller) {
200 if (this.lastTurnedBy != caller) {
201 this.direction = direction;
202 this.lastTurnedBy = caller;
203 } else {
204 System.err.println("Turned by same caller twice: " + caller);
208 public void setMap(Level level) {
209 this.level = level;
212 public boolean isAlive() {
213 return this.alive;
216 public void setAlive(boolean state) {
217 this.alive = state;
220 /** Used to calculate and set a new x-center after x is changed. */
221 private void recalculateCenterX() {
222 this.centerX = this.x + this.width / 2;
225 /** Used to calculate and set a new y-center after y is changed. */
226 private void recalculateCenterY() {
227 this.centerY = this.y + this.height / 2;
231 * Decrease the units currentHealth.
232 * @param damage The number of health points to substract
234 public void damage(int damage) {
235 this.currentHealth -= damage;
239 * Attemts to clone this Unit.
241 * @return A new instance of the same type as the instantiated Unit.
243 @Override
244 public Object clone() {
245 try {
246 return super.clone();
247 } catch (CloneNotSupportedException e) {
248 e.printStackTrace();
249 throw new Error("Object " + this.getClass().getName()
250 + " is not Cloneable");
254 public void collision(Unit unit) {
255 switch (direction) {
256 case UP:
257 if (unit.getDirection() == Direction.DOWN) {
258 setDirection(Direction.DOWN, unit);
259 unit.setDirection(Direction.UP, this);
260 return;
262 break;
263 case DOWN:
264 if (unit.getDirection() == Direction.UP) {
265 setDirection(Direction.UP, unit);
266 unit.setDirection(Direction.DOWN, this);
267 return;
269 break;
270 case LEFT:
271 if (unit.getDirection() == Direction.RIGHT) {
272 setDirection(Direction.RIGHT, unit);
273 unit.setDirection(Direction.LEFT, this);
274 return;
276 break;
277 case RIGHT:
278 if (unit.getDirection() == Direction.LEFT) {
279 setDirection(Direction.LEFT, unit);
280 unit.setDirection(Direction.RIGHT, this);
281 return;
283 break;
284 default:
285 System.err.println("Unit hasn't got a valid Direction");
286 break;
288 this.pause = true;
291 public boolean isPaused() {
292 return this.pause;
295 @Override
296 public String toString() {
297 return getType();
300 public Rectangle getBounds() {
301 return new Rectangle(x, y, width, height);
304 public Rectangle getFutureBounds() {
305 Point nextPoint = getNextPosition();
306 return new Rectangle(nextPoint.x, nextPoint.y, width, height);
309 public boolean intersects(Unit unit) {
310 return this.getBounds().intersects(unit.getBounds());
313 public boolean intersectsNextMove(Unit unit) {
314 return this.getFutureBounds().intersects(unit.getBounds());
317 public void paint(Graphics g) {
318 Image image = images.get(direction);
319 g.drawImage(image, x, y, null);
321 int healthHeight = 2;
322 int yHealth = y + height - healthHeight;
323 g.setColor(Color.RED);
324 g.fillRect(x , yHealth, width, healthHeight);
325 g.setColor(Color.GREEN);
326 int healthBar = (int) (width * (new Double(currentHealth) / health));
327 g.fillRect(x , yHealth, healthBar, healthHeight);