Added number of cleared to scoreboard
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / ATDController.java
blobee9531edf16f1a570f82e45960802ab031944ef9
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.Level;
25 import se.umu.cs.dit06ajnajs.map.MapSquare;
26 import se.umu.cs.dit06ajnajs.map.StartSquare;
28 public class ATDController {
29 private static Logger logger = Logger.getLogger("AntiTD");
31 private final int FRAMES_PER_SECOND = 20;
33 private ATDModel model;
34 private ATDView view;
36 private boolean running;
37 private Thread animationThread;
38 private Thread creditThread;
40 public ATDController(List<Level> levels) {
41 // Create model and view
42 this.model = new ATDModel(levels);
43 this.view = new ATDView(model);
44 connectListeners();
45 newGame();
48 public void newGame() {
49 // TODO: game related init
50 model.newGame();
52 this.running = true;
53 this.animationThread = new Thread(new AnimationThread());
54 this.creditThread = new Thread(new CreditThread());
55 animationThread.start();
56 creditThread.start();
59 private class AnimationThread implements Runnable {
60 public AnimationThread() {
61 // Paint background
62 view.repaintGame();
65 /**
66 * While running, the thread loops through all actions the game can
67 * generate as many times per second determined by the final class
68 * variable FRAMES_PER_SECOND
70 public void run() {
71 // TODO Auto-generated method stub
72 while (running) {
73 List<Agent> agents = model.getAgents();
74 List<Unit> units = new ArrayList<Unit>();
76 // Check for collisions
77 for (Agent agent : agents) {
78 // Extract all units
79 if(agent instanceof Unit) {
80 units.add((Unit)agent);
83 // Pauses all units that will collide next move
84 collisionDetection(units);
86 // Update all agents
87 List<Agent> deadAgents = new ArrayList<Agent>();
88 for (Agent agent : agents) {
89 if (agent.isAlive()) {
90 agent.act();
91 } else {
92 deadAgents.add(agent);
93 logger.info("Dead unit is collected to list deadAgents");
97 if (!deadAgents.isEmpty()) {
98 model.removeAgents(deadAgents);
99 logger.info("Dead agents cleared");
102 // Remove units from goalsquares and count points
103 GoalSquare[] goalSquares = model.getGoalSquares();
104 int credit = 0;
105 int numOfUnits = 0;
106 for (GoalSquare square : goalSquares) {
107 numOfUnits = square.getNumUnits();
108 credit += square.getCredit();
110 if (credit > 0 || numOfUnits > 0) {
111 model.addCredit(credit);
112 model.addGoalUnit(numOfUnits);
113 view.updateScoreboard();
118 // Release Unit from StartSquares
119 StartSquare[] startSquares = model.getStartSquares();
120 for (StartSquare startSquare : startSquares) {
121 Unit unitToStart = startSquare.getUnitToStart();
122 boolean unitToStartCollided = false;
123 if (unitToStart != null) {
124 for (Unit unit : units) {
125 unitToStartCollided = unitToStart.intersects(unit);
126 if (unitToStartCollided) {
127 // Collision
128 break;
131 if (!unitToStartCollided) {
132 // No collision found
133 startSquare.removeUnit(unitToStart);
135 model.releaseUnit(unitToStart);
140 // Repaint all agents
141 Graphics g = view.getGameGraphics();
142 for (Agent agent : agents) {
143 //TODO kan det finnas en agent som inte är paintable?
144 agent.paint(g);
147 // Refresh the game view
148 view.repaintGame();
150 // Try to keep a given number of frames per second.
151 try {
152 Thread.sleep(1000 / FRAMES_PER_SECOND);
153 } catch (InterruptedException e) {
154 System.err.println("Error in thread, exiting.");
155 return;
161 * Examins the units position to each other and pauses units that are
162 * about to collide
164 * //TODO units should not pause, they should slow down.
167 private void collisionDetection(List<Unit> units) {
168 // TODO: Optimize for-loops
169 for (Unit unit : units) {
170 for (Unit otherUnit : units) {
171 if (unit != otherUnit) {
172 if (unit.intersectsNextMove(otherUnit)) {
173 // Collision!
174 unit.collision(otherUnit);
175 System.out.println("Collision");
183 private class CreditThread implements Runnable {
184 public CreditThread() {
189 * While running, the thread sleeps for an interval and then calculates
190 * the earned credits from units on the map. The credits are then added
191 * to the player
193 public void run() {
194 while(running) {
195 try {
196 // Sleep an interval, calculate earned credits, update model
197 Thread.sleep(1000);
198 int credit = calculateCredit();
199 model.addCredit(credit);
200 view.updateScoreboard();
201 } catch (InterruptedException e) {
202 e.printStackTrace();
207 private int calculateCredit() {
208 List<Agent> agents = model.getAgents();
209 List<Unit> units = new ArrayList<Unit>();
210 for (Agent agent : agents) {
211 // Extract all units
212 if(agent instanceof Unit) {
213 units.add((Unit)agent);
216 int credit = units.size() * 10;
217 return credit;
221 /* Connect listeners to View *************************************/
223 private void connectListeners() {
224 this.view.addMapListener(new MapListener());
225 this.view.addClosingListener(new ClosingListener());
226 this.view.addReleaseUnitListener(new ReleaseUnitListener());
227 this.view.addPauseMenuItemListener(new PausResumeListener());
230 /* Inner Listener classes ****************************************/
232 private class MapListener extends MouseAdapter {
233 @Override
234 public void mouseClicked(MouseEvent me) {
235 final int x = me.getX();
236 final int y = me.getY();
238 // SwingUtilities.invokeLater(new Runnable() {
239 // public void run() {
240 // }
241 // });
242 Level level = model.getLevel();
243 final MapSquare square = level.getMapSquareAtPoint(x, y);
244 logger.info("Mouse clicked @ (" + x + ", " + y + ")");
245 logger.info("MapSquare @ " + square);
246 square.click();
247 view.updateBackgroundImage();
248 //if (square instanceof StartSquare) {}
249 //if (square instanceof TurnSquare) {}
253 private class ClosingListener extends WindowAdapter
254 implements ActionListener {
255 public void actionPerformed(ActionEvent ae) {
256 logger.info("Closing program");
257 System.exit(0);
260 @Override
261 public void windowClosing(WindowEvent we) {
262 logger.info("Closing program");
263 System.exit(0);
267 private class PausResumeListener implements ActionListener {
268 public void actionPerformed(ActionEvent ae) {
269 if (running) {
270 ATDController.this.running = false;
271 view.updatePauseMenu("Resume");
272 } else {
273 ATDController.this.running = true;
274 ATDController.this.animationThread
275 = new Thread(new AnimationThread());
276 ATDController.this.creditThread
277 = new Thread(new CreditThread());
278 animationThread.start();
279 creditThread.start();
280 view.updatePauseMenu("Pause");
285 private class ReleaseUnitListener implements ActionListener {
286 public void actionPerformed(ActionEvent ae) {
287 // Release Unit from active StartSquare
288 // TODO: implement
289 System.out.println("hej");
290 AgentPrototypeFactory factory = AgentPrototypeFactory.getInstance();
291 model.addUnit(factory.createUnit(view.getSelectedUnitType()));