lajdlksadlmla
[rmh3093.git] / project2 / FrenzyController.java
blobfb814d69bcc2a566a238b8ee4e6c4e816b5ad137
1 /*
2 * FrenzyController.java
4 * Version:
5 * $Id: FrenzyController.java,v 1.5 2008/05/17 03:29:37 rmh3093 Exp rmh3093 $
7 * Revisions:
8 * $Log: FrenzyController.java,v $
9 * Revision 1.5 2008/05/17 03:29:37 rmh3093
10 * add semi-random movement pattern
12 * Revision 1.4 2008/05/16 23:04:18 rmh3093
13 * implement scrolling pane for last consumed object
15 * Revision 1.3 2008/05/16 22:06:44 rmh3093
16 * meets final submission goals
18 * Revision 1.2 2008/04/30 04:10:52 rmh3093
19 * break out random number generator, first attempt at moving enemies
21 * Revision 1.1 2008/04/26 15:45:41 rmh3093
22 * Initial revision
27 Copyright (c) 2008, Ryan M. Hope
28 All rights reserved.
30 Redistribution and use in source and binary forms, with or without modification,
31 are permitted provided that the following conditions are met:
33 * Redistributions of source code must retain the above copyright notice,
34 this list of conditions and the following disclaimer.
35 * Redistributions in binary form must reproduce the above copyright notice,
36 this list of conditions and the following disclaimer in the documentation
37 and/or other materials provided with the distribution.
38 * Neither the name of the project nor the names of its contributors may be
39 used to endorse or promote products derived from this software without
40 specific prior written permission.
42 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
46 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
49 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 import java.awt.event.*;
55 import java.util.TreeSet;
57 /**
58 * Controls the Frenzy view and updates the model
60 * @author Ryan Hope
62 public class FrenzyController {
64 // Random number generator
65 private BetterRandom betterRandom;
67 private FrenzyModel f_model;
68 private FrenzyView f_view;
70 /**
71 * Create a new Frenzy Controller
73 * @param f_model the Frenzy game f_model
74 * @param f_view the Frenzy game f_view
76 FrenzyController(FrenzyModel f_model, FrenzyView f_view,
77 BetterRandom betterRandom) {
78 this.f_model = f_model;
79 this.f_view = f_view;
80 this.betterRandom = betterRandom;
82 // Add player to board in random position
83 f_model.player = new FrenzyPlayer();
84 spawnPlayer();
86 // Add listeners to f_view
87 f_view.addQuitListener(new QuitListener());
88 f_view.addResetListener(new ResetListener());
89 f_view.addSpawnListener(new SpawnListener());
90 f_view.addPauseListener(new PauseListener());
91 f_view.addPlayerControlsListener(new PlayerControlsListener());
92 f_view.addEnemySpawnListener(new SpawnListener());
93 f_view.addFasterEnemyListener(new FasterEnemyListener());
94 f_view.addSlowerEnemyListener(new SlowerEnemyListener());
97 private void resumeGame() {
98 TreeSet<String> keys =
99 new TreeSet<String>(f_model.enemies.keySet());
100 for (String key : keys) {
101 FrenzyEnemy enemy = f_model.enemies.get(key);
102 if (enemy != null) {
103 synchronized (enemy.moverThread) {
104 enemy.moverThread.notifyAll();
106 // Sleep for a random amount of time so that when enemies wake up
107 // from sleeping they dont look like they are moving in sync
108 try {
109 Thread.sleep(betterRandom.rand.nextInt(50));
110 } catch (InterruptedException e) {
114 synchronized (f_view.enemySpawnerThread) {
115 f_view.enemySpawnerThread.notifyAll();
119 protected synchronized void spawnEnemy() {
120 if (f_model.gamestate) {
121 // Can't spawn new enemies if there are no unique ASCII characters
122 if (f_model.enemyCount < FrenzyModel.MAX_ENIMES) {
124 while (true) {
126 int num = betterRandom.rand.nextInt(255);
128 // These characters don't print
129 if (num < 33 || ((num > 126) && (num < 161)) || num == 173)
130 continue;
132 // Can't use players symbol
133 if (String.valueOf((char)num) == FrenzyPlayer.symbol)
134 continue;
136 // The symbol for the new enemy
137 String symbol = String.valueOf((char)num);
139 // Check to make sure the symbol is already in use
140 if (f_model.enemies.containsKey(symbol)) continue;
142 // Find a random unoccupied location for the enemy to spawn
143 int x = -1;
144 int y = -1;
145 while (true) {
146 x = betterRandom.rand.nextInt(f_model.getBoardSize());
147 y = betterRandom.rand.nextInt(f_model.getBoardSize());
148 if (f_view.boardSquares[y][x].isOccupied() ==
149 FrenzyModel.OCCUPANT.NONE) {
150 break;
154 int move_x = betterRandom.rand.nextInt(2);
155 int move_y = betterRandom.rand.nextInt(2);
156 FrenzyEnemy.MOVEMENT_PATTERN mp = null;
157 // Spawn the new enemy
158 if ((move_x == 1) && (move_y == 1)) {
159 mp = FrenzyEnemy.MOVEMENT_PATTERN.NE;
160 } else if ((move_x == 1) && (move_y == 0)) {
161 mp = FrenzyEnemy.MOVEMENT_PATTERN.SE;
162 } else if ((move_x == 0) && (move_y == 1)) {
163 mp = FrenzyEnemy.MOVEMENT_PATTERN.NW;
164 } else if ((move_x == 0) && (move_y == 0)) {
165 mp = FrenzyEnemy.MOVEMENT_PATTERN.SW;
167 FrenzyEnemy enemy =
168 new FrenzyEnemy(f_model, x, y, symbol, mp,
169 betterRandom.rand.nextInt(3),
170 new EnemyMover(), betterRandom);
171 f_model.enemies.put(symbol, enemy);
172 f_view.addOccupant(enemy, f_view.boardSquares[y][x]);
173 f_model.increaseEnemyCount();
174 enemy.moverThread.start();
175 break;
179 } else {
180 synchronized (f_view.enemySpawnerThread) {
181 try {
182 f_view.enemySpawnerThread.wait();
183 } catch (InterruptedException e) {
190 * Handles moving the Frenzy player around the game board
192 * @author Ryan Hope
194 class PlayerControlsListener implements KeyListener {
196 public void keyPressed(KeyEvent e) {
199 public void keyTyped(KeyEvent e) {
202 // Only perform an action on the release of the key
203 public void keyReleased(KeyEvent e) {
205 if (f_model.gamestate) {
207 int keycode = e.getKeyCode();
208 int x_new = -1;
209 int y_new = -1;
210 int x_old = f_model.player.getXposition();
211 int y_old = f_model.player.getYposition();
212 if ((keycode > 36 && keycode < 41) && f_model.gamestate) {
214 // Remove player from current location
215 f_view.removeOccupant(f_view.boardSquares[y_old][x_old]);
217 switch (keycode) {
219 // Move left
220 case 37:
221 if (x_old == 0) {
222 x_new = f_model.boardsize-1;
223 } else {
224 x_new = x_old-1;
226 y_new = y_old;
227 f_model.player.setXposition(x_new);
228 break;
230 // Move up
231 case 38:
232 if (y_old == 0) {
233 y_new = f_model.boardsize-1;
234 } else {
235 y_new = y_old-1;
237 x_new = x_old;
238 f_model.player.setYposition(y_new);
239 break;
241 // Move right
242 case 39:
243 if (x_old == f_model.boardsize-1) {
244 x_new = 0;
245 } else {
246 x_new = x_old+1;
248 y_new = y_old;
249 f_model.player.setXposition(x_new);
250 break;
252 // Move down
253 case 40:
254 if (y_old == f_model.boardsize-1) {
255 y_new = 0;
256 } else {
257 y_new = y_old+1;
259 x_new = x_old;
260 f_model.player.setYposition(y_new);
261 break;
264 // If new location is occupied by an enemy, eat it
265 if (f_view.boardSquares[y_new][x_new].isOccupied() ==
266 FrenzyModel.OCCUPANT.ENEMY) {
268 // Eat enemy
269 String key =
270 f_view.boardSquares[y_new][x_new].getText();
271 f_model.player.eatEnemy();
272 f_model.decreaseEnemyCount();
273 if (f_model.player.getConsumedCount() > 0 &&
274 f_model.enemyCount==0) {
275 f_model.gamestate = false;
276 f_view.statusLabel.setText("Game over.");
279 // Remove key from list so that the symbol can be reused
280 f_model.enemies.remove(key);
282 // ====================================================
283 // These should be handled by events
285 // Update the last action display
286 f_view.lastActionArea.setText(
287 f_model.player.getSymbol() + " ate " + key +
288 "\n" + f_view.lastActionArea.getText());
290 // Update the consumed enemy count display
291 int count = f_model.player.getConsumedCount();
292 f_view.consumedLabel.setText(String.valueOf(count));
294 // ====================================================
297 // Add player to new square
298 f_view.addOccupant(f_model.player,
299 f_view.boardSquares[y_new][x_new]);
306 * Handles quitting Frenzy
308 * @author Ryan Hope
310 class QuitListener implements ActionListener {
311 public void actionPerformed(ActionEvent e) {
312 f_view.dispose();
313 System.exit(0);
318 * Handles resetting Frenzy
320 * @author Ryan Hope
322 class ResetListener implements ActionListener {
323 public void actionPerformed(ActionEvent e) {
324 f_model.gamestate = true;
325 f_view.statusLabel.setText("Game Running!");
326 f_view.pauseControl.setSelected(false);
327 f_model.player.setConsumedCount(0);
328 f_view.consumedLabel.setText("0");
329 if (f_model.player.dead) {
330 spawnPlayer();
331 f_model.player.dead = false;
333 resumeGame();
338 * Handles resetting Frenzy
340 * @author Ryan Hope
342 class PauseListener implements ActionListener {
343 public void actionPerformed(ActionEvent e) {
344 if (f_view.pauseControl.isSelected()) {
345 f_model.gamestate = false;
346 f_view.statusLabel.setText("Game Paused!");
347 } else {
348 f_model.gamestate = true;
349 if (!f_model.player.dead) resumeGame();
350 f_view.statusLabel.setText("Game Running!");
356 * Handles spawning of new enemies
358 * @author Ryan Hope
360 class SpawnListener implements ActionListener {
362 public void actionPerformed(ActionEvent e) {
363 if (f_model.gamestate) spawnEnemy();
369 * Handles increasing enemy speed
371 * @author Ryan Hope
373 class FasterEnemyListener implements ActionListener {
375 public void actionPerformed(ActionEvent e) {
376 f_model.enemyMoveInterval = f_model.enemyMoveInterval - 10;
382 * Handles decreasing enemy speed
384 * @author Ryan Hope
386 class SlowerEnemyListener implements ActionListener {
388 public void actionPerformed(ActionEvent e) {
389 f_model.enemyMoveInterval = f_model.enemyMoveInterval + 10;
395 * Handles moving enemies
397 * @author Ryan Hope
399 class EnemyMover {
401 public synchronized void move(String symbol) {
402 FrenzyEnemy enemy = f_model.enemies.get(symbol);
403 FrenzyEnemy eaten = null;
404 if (enemy != null) {
405 int x = enemy.getXposition();
406 int y = enemy.getYposition();
407 FrenzyModel.OCCUPANT occupant_t =
408 f_view.boardSquares[y][x].isOccupied();
409 if (occupant_t != FrenzyModel.OCCUPANT.NONE) {
410 String occupant = f_view.boardSquares[y][x].getText();
411 if (occupant_t == FrenzyModel.OCCUPANT.PLAYER) {
412 f_model.gamestate = false;
413 f_model.player.dead = true;
414 f_view.statusLabel.setText("Game over.");
415 } else {
416 eaten = f_model.enemies.get(occupant);
417 if (eaten == null) {
418 // what causes this?
419 System.out.println("Oh no!");
420 } else {
421 eaten.move = false;
423 f_model.enemies.remove(occupant);
425 f_view.lastActionArea.setText(
426 symbol + " ate " + occupant +
427 "\n" + f_view.lastActionArea.getText());
429 f_view.removeOccupant(
430 f_view.boardSquares[enemy.Yposition_old][enemy.Xposition_old]);
431 f_view.addOccupant(enemy, f_view.boardSquares[y][x]);
437 private void spawnPlayer() {
438 while (true) {
439 int x = betterRandom.rand.nextInt(f_model.boardsize);
440 int y = betterRandom.rand.nextInt(f_model.boardsize);
441 if (f_view.boardSquares[y][x].isOccupied() ==
442 FrenzyModel.OCCUPANT.NONE) {
443 f_model.player.setXposition(x);
444 f_model.player.setYposition(y);
445 break;
448 f_view.spawnPlayer();