First try in collision detection
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / ATDController.java
blob2cc77c95301ed35003e2f5d695b19bfc71c26270
1 package se.umu.cs.dit06ajnajs;
4 import java.awt.Graphics;
5 import java.awt.Point;
6 import java.awt.event.MouseAdapter;
7 import java.awt.event.MouseEvent;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.logging.Logger;
13 import java.awt.event.ActionEvent;
14 import java.awt.event.ActionListener;
15 import java.awt.event.WindowAdapter;
16 import java.awt.event.WindowEvent;
18 import se.umu.cs.dit06ajnajs.agent.Agent;
19 import se.umu.cs.dit06ajnajs.agent.AgentPrototypeFactory;
20 import se.umu.cs.dit06ajnajs.agent.BasicTower;
21 import se.umu.cs.dit06ajnajs.agent.Direction;
22 import se.umu.cs.dit06ajnajs.agent.Unit;
23 import se.umu.cs.dit06ajnajs.map.GoalSquare;
24 import se.umu.cs.dit06ajnajs.map.StartSquare;
25 import se.umu.cs.dit06ajnajs.map.Map;
26 import se.umu.cs.dit06ajnajs.map.MapSquare;
27 import javax.swing.SwingUtilities;
29 public class ATDController {
30 private static Logger logger = Logger.getLogger("AntiTD");
32 private final int FRAMES_PER_SECOND = 20;
34 private ATDModel model;
35 private ATDView view;
37 private boolean running;
38 private Thread animationThread;
40 public ATDController(List<Map> maps) {
41 // Create model and view
42 model = new ATDModel(maps);
43 view = new ATDView(model);
44 connectListeners();
45 initGame();
46 running = true;
47 animationThread = new Thread(new AnimationThread());
48 animationThread.start();
51 public void initGame() {
52 // TODO: game related init
54 // Factory used to create units, Unit details are hardcoded in factory:
55 // speed, cost etc
56 AgentPrototypeFactory factory = AgentPrototypeFactory.getInstance();
57 model.addAgent(factory.createUnit("FootmanUnit", 100 - 46, 200,
58 Direction.UP, model.getMap()));
60 model.addTower(new BasicTower(41, 41, 1, (int) (AntiTD.SQUARE_SIZE*1.5)));
61 //model.addTower(new BasicTower(20, 20, 10, (int) (AntiTD.SQUARE_SIZE * 2.5)));
64 private class AnimationThread implements Runnable {
65 public void run() {
66 // TODO Auto-generated method stub
67 // Paint background
68 view.repaintGame();
70 while (running) {
71 List<Agent> agents = model.getAgents();
72 List<Unit> units = new ArrayList<Unit>();
74 // Check for collisions
75 for (Agent agent : agents) {
76 // Extract all units
77 if(agent instanceof Unit) {
78 units.add((Unit)agent);
81 collisionDetection(units);
83 // Update all agents
84 List<Agent> deadAgents = new ArrayList<Agent>();
85 for (Agent agent : agents) {
86 if (agent.isAlive()) {
87 agent.act();
88 } else {
89 deadAgents.add(agent);
90 logger.info("Dead unit is collected to list deadAgents");
94 if (!deadAgents.isEmpty()) {
95 agents.removeAll(deadAgents);
96 logger.info("Dead agents cleared");
99 // Remove units from goalsquares and count points
100 GoalSquare[] goalSquares = model.getGoalSquares();
101 for (GoalSquare square : goalSquares) {
102 List<Unit> goalUnits = square.getUnits();
103 if (goalUnits != null) {
104 for (Unit unit : goalUnits) {
105 agents.remove(unit);
106 // TODO At tower can still have a pointer to the removed unit
107 logger.info("Unit >" + unit.getClass().getSimpleName() +
108 "< has reached a goal and is now removed");
109 // TODO count points
111 goalUnits.clear();
115 // Repaint all agents
116 Graphics g = view.getGameGraphics();
117 for (Agent agent : agents) {
118 //TODO kan det finnas en agent som inte är paintable?
119 agent.paint(g);
122 // Refresh the game view
123 view.repaintGame();
125 // Try to keep a given number of frames per second.
126 try {
127 Thread.sleep(1000 / FRAMES_PER_SECOND);
128 } catch (InterruptedException e) {
129 System.err.println("Error in thread, exiting.");
130 return;
136 * Examins the units position to each other and pauses units that are
137 * about to collide
139 * //TODO units should not pause, they should slow down.
142 private void collisionDetection(List<Unit> units) {
143 for (Unit unit : units) {
145 // Calculate next position
146 Direction direction = unit.getDirection();
147 int x = unit.getX();
148 int y = unit.getY();
149 int speed = unit.getSpeed();
150 Point newPoint = null;
151 switch (direction) {
152 case UP:
153 newPoint = new Point(x, y - speed);
154 case DOWN:
155 newPoint = new Point(x, y + speed);
156 case LEFT:
157 newPoint = new Point(x - speed, y);
158 case RIGHT:
159 newPoint = new Point(x + speed, y);
160 default:
161 System.err.println("Unit has not got a valid Direction");
162 // TODO catch nullpointerexception?
165 // The current units next position
166 int nextX1 = newPoint.x;
167 int nextX2 = nextX1 + unit.getWidth();
168 int nextY1 = newPoint.y;
169 int nextY2 = nextY1 + unit.getHeight();
172 // Look for collisions
173 for (Unit otherUnit : units) {
174 if (unit != otherUnit) {
175 int otherX1 = otherUnit.getX();
176 int otherX2 = otherX1 + otherUnit.getWidth();
177 int otherY1 = otherUnit.getY();
178 int otherY2 = otherY1 + otherUnit.getHeight();
180 switch (direction) {
181 case UP:
182 // FLUMMIG ALGORITMBESKRIVNING FÖR UP:
183 // (unit1 övre kant kommer över unit2 nedre kant i y-led)
184 // otherY2 < nextY1
185 // &&
186 // (unit1 vänster kant ligger mellan unit2 kanter ELLER unit1 höger kant ligger mellan unit2 kanter
187 // otherX1 < nextX1 < otherY2 || otherX1 < nextX1 < otherY2
189 if( (nextY1 < otherY2) &&
190 ( ((nextX1 > otherX1) && (nextX1 < otherX2)) || ((nextX2 > otherX1) && (nextX2 < otherX2)))) {
191 // Collision!
192 this.setCollision(unit, otherUnit);
194 break;
195 case DOWN:
196 if( (nextY2 > otherY1) && ( ((nextX1 > otherX1) && (nextX1 < otherX2)) || ((nextX2 > otherX1) && (nextX2 < otherX2)))) {
197 // Collision!
200 break;
201 case LEFT:
202 if( (nextX2 > otherX1) && ( ((nextY1 > otherY1) && (nextY1 < otherY2)) || ((nextY2 > otherY1) && (nextY2 < otherY2)))) {
203 // Collision!
205 break;
206 case RIGHT:
207 if( (nextX1 < otherX2) && ( ((nextY1 > otherY1) && (nextY1 < otherY2)) || ((nextY2 > otherY1) && (nextY2 < otherY2)))) {
208 // Collision!
210 break;
211 default:
212 System.err.println("Unit has not got a valid Direction");
213 // TODO catch nullpointerexception?
214 break;
222 * Pauses the unit
223 * //TODO Implement slower speed, not pause. The method does not
224 * use the other unit in this implementation
225 * @param unit
226 * @param otherUnit
228 private void setCollision(Unit unit, Unit otherUnit) {
229 unit.setPause(true);
233 /* Connect listeners to View *************************************/
235 private void connectListeners() {
236 this.view.addMapListener(new MapListener());
237 this.view.addClosingListener(new ClosingListener());
240 /* Inner Listener classes ****************************************/
242 private class MapListener extends MouseAdapter {
243 @Override
244 public void mouseClicked(MouseEvent me) {
245 final int x = me.getX();
246 final int y = me.getY();
248 // SwingUtilities.invokeLater(new Runnable() {
249 // public void run() {
250 // }
251 // });
252 Map map = model.getMap();
253 final MapSquare square = map.getMapSquareAtPoint(x, y);
254 logger.info("Mouse clicked @ (" + x + ", " + y + ")");
255 logger.info("MapSquare @ " + square);
256 square.click();
257 view.updateBackgroundImage();
258 //if (square instanceof StartSquare) {}
259 //if (square instanceof TurnSquare) {}
263 private class ClosingListener extends WindowAdapter
264 implements ActionListener {
265 public void actionPerformed(ActionEvent ae) {
266 logger.info("Closing program");
267 System.exit(0);
270 @Override
271 public void windowClosing(WindowEvent we) {
272 logger.info("Closing program");
273 System.exit(0);