Merge branch 'master' of ssh://repo.or.cz/srv/git/AntiTD
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / ATDController.java
blob38745dd51c744b508bddc5d7323115c9b299b310
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);
84 // Update all agents
85 List<Agent> deadAgents = new ArrayList<Agent>();
86 for (Agent agent : agents) {
87 if (agent.isAlive()) {
88 if (agent instanceof Unit) {
89 // Collisioncheck
90 for (Unit unit : units) {
91 if (agent != unit) {
92 if (((Unit) agent).intersectsNextMove(unit)) {
93 // Collision!
94 ((Unit) agent).collision(unit);
98 agent.act();
99 } else {
100 agent.act();
102 } else {
103 deadAgents.add(agent);
104 logger.info("Dead unit is collected to list deadAgents");
107 if (!deadAgents.isEmpty()) {
108 model.removeAgents(deadAgents);
109 logger.info("Dead agents cleared");
112 // Remove units from goalsquares and count points
113 GoalSquare[] goalSquares = model.getGoalSquares();
114 int credit = 0;
115 int numOfUnits = 0;
116 for (GoalSquare square : goalSquares) {
117 numOfUnits = square.getNumUnits();
118 credit += square.getCredit();
120 if (credit > 0 || numOfUnits > 0) {
121 model.addCredit(credit);
122 model.addGoalUnit(numOfUnits);
123 view.updateScoreboard();
128 // Release Unit from StartSquares
129 StartSquare[] startSquares = model.getStartSquares();
130 for (StartSquare startSquare : startSquares) {
131 Unit unitToStart = startSquare.getUnitToStart();
132 boolean unitToStartCollided = false;
133 if (unitToStart != null) {
134 for (Unit unit : units) {
135 unitToStartCollided = unitToStart.intersects(unit);
136 if (unitToStartCollided) {
137 // Collision
138 break;
141 if (!unitToStartCollided) {
142 // No collision found
143 startSquare.removeUnit(unitToStart);
145 model.releaseUnit(unitToStart);
150 // Repaint all agents
151 Graphics g = view.getGameGraphics();
152 for (Agent agent : agents) {
153 //TODO kan det finnas en agent som inte är paintable?
154 agent.paint(g);
157 // Refresh the game view
158 view.repaintGame();
160 // Try to keep a given number of frames per second.
161 try {
162 Thread.sleep(1000 / FRAMES_PER_SECOND);
163 } catch (InterruptedException e) {
164 System.err.println("Error in thread, exiting.");
165 return;
171 private class CreditThread implements Runnable {
172 public CreditThread() {
177 * While running, the thread sleeps for an interval and then calculates
178 * the earned credits from units on the map. The credits are then added
179 * to the player
181 public void run() {
182 while(running) {
183 try {
184 // Sleep an interval, calculate earned credits, update model
185 Thread.sleep(1000);
186 int credit = calculateCredit();
187 model.addCredit(credit);
188 view.updateScoreboard();
189 } catch (InterruptedException e) {
190 e.printStackTrace();
195 private int calculateCredit() {
196 List<Agent> agents = model.getAgents();
197 List<Unit> units = new ArrayList<Unit>();
198 for (Agent agent : agents) {
199 // Extract all units
200 if(agent instanceof Unit) {
201 units.add((Unit)agent);
204 int credit = units.size() * 10;
205 return credit;
209 /* Connect listeners to View *************************************/
211 private void connectListeners() {
212 this.view.addMapListener(new MapListener());
213 this.view.addClosingListener(new ClosingListener());
214 this.view.addReleaseUnitListener(new ReleaseUnitListener());
215 this.view.addPauseMenuItemListener(new PausResumeListener());
218 /* Inner Listener classes ****************************************/
220 private class MapListener extends MouseAdapter {
221 @Override
222 public void mouseClicked(MouseEvent me) {
223 final int x = me.getX();
224 final int y = me.getY();
226 // SwingUtilities.invokeLater(new Runnable() {
227 // public void run() {
228 // }
229 // });
230 Level level = model.getLevel();
231 final MapSquare square = level.getMapSquareAtPoint(x, y);
232 logger.info("Mouse clicked @ (" + x + ", " + y + ")");
233 logger.info("MapSquare @ " + square);
234 square.click();
235 view.updateBackgroundImage();
236 //if (square instanceof StartSquare) {}
237 //if (square instanceof TurnSquare) {}
241 private class ClosingListener extends WindowAdapter
242 implements ActionListener {
243 public void actionPerformed(ActionEvent ae) {
244 logger.info("Closing program");
245 System.exit(0);
248 @Override
249 public void windowClosing(WindowEvent we) {
250 logger.info("Closing program");
251 System.exit(0);
255 private class PausResumeListener implements ActionListener {
256 public void actionPerformed(ActionEvent ae) {
257 if (running) {
258 ATDController.this.running = false;
259 view.updatePauseMenu("Resume");
260 } else {
261 ATDController.this.running = true;
262 ATDController.this.animationThread
263 = new Thread(new AnimationThread());
264 ATDController.this.creditThread
265 = new Thread(new CreditThread());
266 animationThread.start();
267 creditThread.start();
268 view.updatePauseMenu("Pause");
273 private class ReleaseUnitListener implements ActionListener {
274 public void actionPerformed(ActionEvent ae) {
275 // Release Unit from active StartSquare
276 // TODO: implement
277 System.out.println("hej");
278 AgentPrototypeFactory factory = AgentPrototypeFactory.getInstance();
279 model.addUnit(factory.createUnit(view.getSelectedUnitType()));