1 | package jpacman.controller; |
2 | |
3 | import java.awt.event.ActionEvent; |
4 | import java.awt.event.ActionListener; |
5 | import java.util.Random; |
6 | import java.util.Vector; |
7 | |
8 | import javax.swing.Timer; |
9 | |
10 | import jpacman.model.Engine; |
11 | import jpacman.model.Monster; |
12 | |
13 | /** |
14 | * A controller which generates a monster move at regular intervals. The actual |
15 | * move generation is deferred to subclasses, which can use their own moving |
16 | * strategy. As more different monster controller subclasses are created, more |
17 | * shared monster moving methods can be put in this class. |
18 | * <p> |
19 | * |
20 | * @author Arie van Deursen, 3 September, 2003 |
21 | * @version $Id: AbstractMonsterController.java,v 1.1 2006/08/29 14:49:23 arie |
22 | * Exp $ |
23 | */ |
24 | public abstract class AbstractMonsterController implements ActionListener, |
25 | IMonsterController { |
26 | |
27 | /** |
28 | * Randomizer used to pick, e.g., a monster at random. |
29 | */ |
30 | private static Random randomizer = new Random(); |
31 | |
32 | /** |
33 | * Timer to be used to trigger monster moves. |
34 | */ |
35 | private Timer timer; |
36 | |
37 | /** |
38 | * Vector of monsters that are to be moved. |
39 | */ |
40 | private Vector<Monster> monsters; |
41 | |
42 | /** |
43 | * Underlying game engine. |
44 | */ |
45 | private Engine theEngine; |
46 | |
47 | /** |
48 | * The default delay between monster moves. |
49 | */ |
50 | public static final int DELAY = 50; |
51 | |
52 | /** |
53 | * Create a new monstercontroller using the default |
54 | * delay and the given game engine. |
55 | * |
56 | * @param e |
57 | * The underlying model of the game. |
58 | */ |
59 | public AbstractMonsterController(Engine e) { |
60 | theEngine = e; |
61 | timer = new Timer(DELAY, this); |
62 | assert controllerInvariant(); |
63 | } |
64 | |
65 | /** |
66 | * Variable that should always be set. |
67 | * @return true iff all vars non-null. |
68 | */ |
69 | protected boolean controllerInvariant() { |
70 | return timer != null && theEngine != null; |
71 | } |
72 | |
73 | /** |
74 | * ActionListener event caught when timer ticks. |
75 | * @param e Event caught. |
76 | */ |
77 | public void actionPerformed(ActionEvent e) { |
78 | assert controllerInvariant(); |
79 | doTick(); |
80 | assert controllerInvariant(); |
81 | } |
82 | |
83 | /** |
84 | * @see jpacman.controller.IMonsterController#start() |
85 | */ |
86 | public synchronized void start() { |
87 | assert controllerInvariant(); |
88 | // the game may have been restarted -- refresh the monster list |
89 | // contained. |
90 | monsters = theEngine.getMonsters(); |
91 | timer.start(); |
92 | assert controllerInvariant(); |
93 | assert monsters != null; |
94 | } |
95 | |
96 | /** |
97 | * @see jpacman.controller.IMonsterController#stop() |
98 | */ |
99 | public synchronized void stop() { |
100 | assert controllerInvariant(); |
101 | timer.stop(); |
102 | assert controllerInvariant(); |
103 | } |
104 | |
105 | /** |
106 | * Return a randomly chosen monster, or null if there |
107 | * are no monsters in this game. |
108 | * @return Random monster or null; |
109 | */ |
110 | protected Monster getRandomMonster() { |
111 | Monster theMonster = null; |
112 | if (monsters.size() > 0) { |
113 | int monsterIndex = randomizer.nextInt(monsters.size()); |
114 | theMonster = monsters.elementAt(monsterIndex); |
115 | } |
116 | return theMonster; |
117 | } |
118 | |
119 | /** |
120 | * Obtain the randomizer used for monster moves. |
121 | * @return the randomizer. |
122 | */ |
123 | protected static Random getRandomizer() { |
124 | return randomizer; |
125 | } |
126 | |
127 | /** |
128 | * @return The Engine containing the monsters. |
129 | */ |
130 | protected Engine getEngine() { |
131 | return theEngine; |
132 | } |
133 | } |