Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/state/StateBasedGame.java
1457 views
1
package org.newdawn.slick.state;
2
3
import java.util.HashMap;
4
import java.util.Iterator;
5
6
import org.newdawn.slick.Game;
7
import org.newdawn.slick.GameContainer;
8
import org.newdawn.slick.Graphics;
9
import org.newdawn.slick.Input;
10
import org.newdawn.slick.InputListener;
11
import org.newdawn.slick.SlickException;
12
import org.newdawn.slick.state.transition.EmptyTransition;
13
import org.newdawn.slick.state.transition.Transition;
14
15
/**
16
* A state based game isolated different stages of the game (menu, ingame, hiscores, etc) into
17
* different states so they can be easily managed and maintained.
18
*
19
* @author kevin
20
*/
21
public abstract class StateBasedGame implements Game, InputListener {
22
/** The list of states making up this game */
23
private HashMap states = new HashMap();
24
/** The current state */
25
private GameState currentState;
26
/** The next state we're moving into */
27
private GameState nextState;
28
/** The container holding this game */
29
private GameContainer container;
30
/** The title of the game */
31
private String title;
32
33
/** The transition being used to enter the state */
34
private Transition enterTransition;
35
/** The transition being used to leave the state */
36
private Transition leaveTransition;
37
38
/**
39
* Create a new state based game
40
*
41
* @param name The name of the game
42
*/
43
public StateBasedGame(String name) {
44
this.title = name;
45
46
currentState = new BasicGameState() {
47
public int getID() {
48
return -1;
49
}
50
public void init(GameContainer container, StateBasedGame game) throws SlickException {
51
}
52
public void render(StateBasedGame game, Graphics g) throws SlickException {
53
}
54
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
55
}
56
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
57
}
58
};
59
}
60
61
/**
62
* @see org.newdawn.slick.ControlledInputReciever#inputStarted()
63
*/
64
public void inputStarted() {
65
66
}
67
68
/**
69
* Get the number of states that have been added to this game
70
*
71
* @return The number of states that have been added to this game
72
*/
73
public int getStateCount() {
74
return states.keySet().size();
75
}
76
77
/**
78
* Get the ID of the state the game is currently in
79
*
80
* @return The ID of the state the game is currently in
81
*/
82
public int getCurrentStateID() {
83
return currentState.getID();
84
}
85
86
/**
87
* Get the state the game is currently in
88
*
89
* @return The state the game is currently in
90
*/
91
public GameState getCurrentState() {
92
return currentState;
93
}
94
95
/**
96
* @see org.newdawn.slick.InputListener#setInput(org.newdawn.slick.Input)
97
*/
98
public void setInput(Input input) {
99
}
100
101
/**
102
* Add a state to the game. The state will be updated and maintained
103
* by the game
104
*
105
* @param state The state to be added
106
*/
107
public void addState(GameState state) {
108
states.put(new Integer(state.getID()), state);
109
110
if (currentState.getID() == -1) {
111
currentState = state;
112
}
113
}
114
115
/**
116
* Get a state based on it's identifier
117
*
118
* @param id The ID of the state to retrieve
119
* @return The state requested or null if no state with the specified ID exists
120
*/
121
public GameState getState(int id) {
122
return (GameState) states.get(new Integer(id));
123
}
124
125
/**
126
* Enter a particular game state with no transition
127
*
128
* @param id The ID of the state to enter
129
*/
130
public void enterState(int id) {
131
enterState(id, new EmptyTransition(), new EmptyTransition());
132
}
133
134
/**
135
* Enter a particular game state with the transitions provided
136
*
137
* @param id The ID of the state to enter
138
* @param leave The transition to use when leaving the current state
139
* @param enter The transition to use when entering the new state
140
*/
141
public void enterState(int id, Transition leave, Transition enter) {
142
if (leave == null) {
143
leave = new EmptyTransition();
144
}
145
if (enter == null) {
146
enter = new EmptyTransition();
147
}
148
leaveTransition = leave;
149
enterTransition = enter;
150
151
nextState = getState(id);
152
if (nextState == null) {
153
throw new RuntimeException("No game state registered with the ID: "+id);
154
}
155
156
leaveTransition.init(currentState, nextState);
157
}
158
159
/**
160
* @see org.newdawn.slick.BasicGame#init(org.newdawn.slick.GameContainer)
161
*/
162
public final void init(GameContainer container) throws SlickException {
163
this.container = container;
164
initStatesList(container);
165
166
Iterator gameStates = states.values().iterator();
167
168
while (gameStates.hasNext()) {
169
GameState state = (GameState) gameStates.next();
170
171
state.init(container, this);
172
}
173
174
if (currentState != null) {
175
currentState.enter(container, this);
176
}
177
}
178
179
/**
180
* Initialise the list of states making up this game
181
*
182
* @param container The container holding the game
183
* @throws SlickException Indicates a failure to initialise the state based game resources
184
*/
185
public abstract void initStatesList(GameContainer container) throws SlickException;
186
187
/**
188
* @see org.newdawn.slick.Game#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
189
*/
190
public final void render(GameContainer container, Graphics g) throws SlickException {
191
preRenderState(container, g);
192
193
if (leaveTransition != null) {
194
leaveTransition.preRender(this, container, g);
195
} else if (enterTransition != null) {
196
enterTransition.preRender(this, container, g);
197
}
198
199
currentState.render(container, this, g);
200
201
if (leaveTransition != null) {
202
leaveTransition.postRender(this, container, g);
203
} else if (enterTransition != null) {
204
enterTransition.postRender(this, container, g);
205
}
206
207
postRenderState(container, g);
208
}
209
210
/**
211
* User hook for rendering at the before the current state
212
* and/or transition have been rendered
213
*
214
* @param container The container in which the game is hosted
215
* @param g The graphics context on which to draw
216
* @throws SlickException Indicates a failure within render
217
*/
218
protected void preRenderState(GameContainer container, Graphics g) throws SlickException {
219
// NO-OP
220
}
221
222
/**
223
* User hook for rendering at the game level after the current state
224
* and/or transition have been rendered
225
*
226
* @param container The container in which the game is hosted
227
* @param g The graphics context on which to draw
228
* @throws SlickException Indicates a failure within render
229
*/
230
protected void postRenderState(GameContainer container, Graphics g) throws SlickException {
231
// NO-OP
232
}
233
234
/**
235
* @see org.newdawn.slick.BasicGame#update(org.newdawn.slick.GameContainer, int)
236
*/
237
public final void update(GameContainer container, int delta) throws SlickException {
238
preUpdateState(container, delta);
239
240
if (leaveTransition != null) {
241
leaveTransition.update(this, container, delta);
242
if (leaveTransition.isComplete()) {
243
currentState.leave(container, this);
244
GameState prevState = currentState;
245
currentState = nextState;
246
nextState = null;
247
leaveTransition = null;
248
if (enterTransition == null) {
249
currentState.enter(container, this);
250
} else {
251
enterTransition.init(currentState, prevState);
252
}
253
} else {
254
return;
255
}
256
}
257
258
if (enterTransition != null) {
259
enterTransition.update(this, container, delta);
260
if (enterTransition.isComplete()) {
261
currentState.enter(container, this);
262
enterTransition = null;
263
} else {
264
return;
265
}
266
}
267
268
currentState.update(container, this, delta);
269
270
postUpdateState(container, delta);
271
}
272
273
/**
274
* User hook for updating at the game before the current state
275
* and/or transition have been updated
276
*
277
* @param container The container in which the game is hosted
278
* @param delta The amount of time in milliseconds since last update
279
* @throws SlickException Indicates a failure within render
280
*/
281
protected void preUpdateState(GameContainer container, int delta) throws SlickException {
282
// NO-OP
283
}
284
285
/**
286
* User hook for rendering at the game level after the current state
287
* and/or transition have been updated
288
*
289
* @param container The container in which the game is hosted
290
* @param delta The amount of time in milliseconds since last update
291
* @throws SlickException Indicates a failure within render
292
*/
293
protected void postUpdateState(GameContainer container, int delta) throws SlickException {
294
// NO-OP
295
}
296
297
/**
298
* Check if the game is transitioning between states
299
*
300
* @return True if we're transitioning between states
301
*/
302
private boolean transitioning() {
303
return (leaveTransition != null) || (enterTransition != null);
304
}
305
306
/**
307
* @see org.newdawn.slick.Game#closeRequested()
308
*/
309
public boolean closeRequested() {
310
return true;
311
}
312
313
/**
314
* @see org.newdawn.slick.Game#getTitle()
315
*/
316
public String getTitle() {
317
return title;
318
}
319
320
/**
321
* Get the container holding this game
322
*
323
* @return The game container holding this game
324
*/
325
public GameContainer getContainer() {
326
return container;
327
}
328
329
/**
330
* @see org.newdawn.slick.InputListener#controllerButtonPressed(int, int)
331
*/
332
public void controllerButtonPressed(int controller, int button) {
333
if (transitioning()) {
334
return;
335
}
336
337
currentState.controllerButtonPressed(controller, button);
338
}
339
340
/**
341
* @see org.newdawn.slick.InputListener#controllerButtonReleased(int, int)
342
*/
343
public void controllerButtonReleased(int controller, int button) {
344
if (transitioning()) {
345
return;
346
}
347
348
currentState.controllerButtonReleased(controller, button);
349
}
350
351
/**
352
* @see org.newdawn.slick.InputListener#controllerDownPressed(int)
353
*/
354
public void controllerDownPressed(int controller) {
355
if (transitioning()) {
356
return;
357
}
358
359
currentState.controllerDownPressed(controller);
360
}
361
362
/**
363
* @see org.newdawn.slick.InputListener#controllerDownReleased(int)
364
*/
365
public void controllerDownReleased(int controller) {
366
if (transitioning()) {
367
return;
368
}
369
370
currentState.controllerDownReleased(controller);
371
}
372
373
/**
374
* @see org.newdawn.slick.InputListener#controllerLeftPressed(int)
375
*/
376
public void controllerLeftPressed(int controller) {
377
if (transitioning()) {
378
return;
379
}
380
381
currentState.controllerLeftPressed(controller);
382
}
383
384
/**
385
* @see org.newdawn.slick.InputListener#controllerLeftReleased(int)
386
*/
387
public void controllerLeftReleased(int controller) {
388
if (transitioning()) {
389
return;
390
}
391
392
currentState.controllerLeftReleased(controller);
393
}
394
395
/**
396
* @see org.newdawn.slick.InputListener#controllerRightPressed(int)
397
*/
398
public void controllerRightPressed(int controller) {
399
if (transitioning()) {
400
return;
401
}
402
403
currentState.controllerRightPressed(controller);
404
}
405
406
/**
407
* @see org.newdawn.slick.InputListener#controllerRightReleased(int)
408
*/
409
public void controllerRightReleased(int controller) {
410
if (transitioning()) {
411
return;
412
}
413
414
currentState.controllerRightReleased(controller);
415
}
416
417
/**
418
* @see org.newdawn.slick.InputListener#controllerUpPressed(int)
419
*/
420
public void controllerUpPressed(int controller) {
421
if (transitioning()) {
422
return;
423
}
424
425
currentState.controllerUpPressed(controller);
426
}
427
428
/**
429
* @see org.newdawn.slick.InputListener#controllerUpReleased(int)
430
*/
431
public void controllerUpReleased(int controller) {
432
if (transitioning()) {
433
return;
434
}
435
436
currentState.controllerUpReleased(controller);
437
}
438
439
/**
440
* @see org.newdawn.slick.InputListener#keyPressed(int, char)
441
*/
442
public void keyPressed(int key, char c) {
443
if (transitioning()) {
444
return;
445
}
446
447
currentState.keyPressed(key, c);
448
}
449
450
/**
451
* @see org.newdawn.slick.InputListener#keyReleased(int, char)
452
*/
453
public void keyReleased(int key, char c) {
454
if (transitioning()) {
455
return;
456
}
457
458
currentState.keyReleased(key, c);
459
}
460
461
/**
462
* @see org.newdawn.slick.InputListener#mouseMoved(int, int, int, int)
463
*/
464
public void mouseMoved(int oldx, int oldy, int newx, int newy) {
465
if (transitioning()) {
466
return;
467
}
468
469
currentState.mouseMoved(oldx, oldy, newx, newy);
470
}
471
472
/**
473
* @see org.newdawn.slick.InputListener#mouseDragged(int, int, int, int)
474
*/
475
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
476
if (transitioning()) {
477
return;
478
}
479
480
currentState.mouseDragged(oldx, oldy, newx, newy);
481
}
482
/**
483
* @see org.newdawn.slick.InputListener#mouseClicked(int, int, int, int)
484
*/
485
public void mouseClicked(int button, int x, int y, int clickCount) {
486
if (transitioning()) {
487
return;
488
}
489
490
currentState.mouseClicked(button, x, y, clickCount);
491
}
492
493
/**
494
* @see org.newdawn.slick.InputListener#mousePressed(int, int, int)
495
*/
496
public void mousePressed(int button, int x, int y) {
497
if (transitioning()) {
498
return;
499
}
500
501
currentState.mousePressed(button, x, y);
502
}
503
504
/**
505
* @see org.newdawn.slick.InputListener#mouseReleased(int, int, int)
506
*/
507
public void mouseReleased(int button, int x, int y) {
508
if (transitioning()) {
509
return;
510
}
511
512
currentState.mouseReleased(button, x, y);
513
}
514
515
/**
516
* @see org.newdawn.slick.InputListener#isAcceptingInput()
517
*/
518
public boolean isAcceptingInput() {
519
if (transitioning()) {
520
return false;
521
}
522
523
return currentState.isAcceptingInput();
524
}
525
526
/**
527
* @see org.newdawn.slick.InputListener#inputEnded()
528
*/
529
public void inputEnded() {
530
}
531
532
/**
533
* @see org.newdawn.slick.InputListener#mouseWheelMoved(int)
534
*/
535
public void mouseWheelMoved(int newValue) {
536
if (transitioning()) {
537
return;
538
}
539
540
currentState.mouseWheelMoved(newValue);
541
}
542
543
}
544
545