Subversion Repositories AndroidProjects

Rev

Rev 856 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
835 chris 1
package com.gebauz.bauzoid.gamestates;
2
 
3
import java.lang.reflect.InvocationTargetException;
4
 
5
import com.badlogic.gdx.Gdx;
6
import com.gebauz.bauzoid.app.Consts;
7
import com.gebauz.bauzoid.game.Game;
8
import com.gebauz.bauzoid.game.GameObject;
9
import com.gebauz.bauzoid.math.MathUtil;
10
 
11
/** Manages game state switching, updating, rendering, and initialization/destruction. */
12
public class GameStateManager extends GameObject
13
{
14
        // Constants========================================================================================
15
 
16
        static final float FADE_TIME = 0.4f;
17
 
18
        // Embedded Types===================================================================================
19
 
20
        private enum StateMode
21
        {
22
                MODE_NORMAL,            // everything normal
23
                MODE_FADEIN,            // fade in
24
                MODE_FADEOUT,           // fade out
25
                MODE_EXIT_STATE,        // during exiting a state
26
                MODE_INIT_STATE,        // during loading a state
27
        };
28
 
29
        // Fields===========================================================================================
30
 
31
        private BaseGameState mCurrentState = null;
32
        private Class<? extends BaseGameState> mNextStateClass = null;
33
        private String mParam = "";
34
        private StateMode mStateMode = StateMode.MODE_NORMAL;
35
 
36
        /** Tracks how much time was spend in each state mode. */
37
        private float mStateModeTimer = 0.0f;
38
 
39
        /** The default package name for the actual game's gamestates. */
40
        private String mDefaultPackage = "";
41
 
42
        private ScreenFader mScreenFader = null;
43
 
44
        private BaseLoadingScreen mLoadingScreen = null;
45
 
46
        // Methods==========================================================================================
47
 
48
        /** Constructor. */
49
        public GameStateManager(Game game)
50
        {
51
                super(game);           
52
        }
53
 
54
        /** Called when the GameStateManager should initially set up its internals. */
55
        public void init()
56
        {
57
                mScreenFader = new ScreenFader(getGame().getGraphics());
58
                mScreenFader.init();
59
        }
60
 
61
        /** Called when the GameStateManager should clean up. */
62
        public void exit()
63
        {
64
                if (mScreenFader != null)
65
                {
66
                        mScreenFader.exit();
67
                        mScreenFader = null;
68
                }
69
 
70
                if (mCurrentState != null)
71
                {
72
                        // reset everything
73
 
74
                        mCurrentState.exit();
75
                        mCurrentState = null;
76
 
77
                        mNextStateClass = null;
78
                        mStateMode = StateMode.MODE_NORMAL;
79
                        mStateModeTimer = 0.0f;
80
                }
81
        }
82
 
83
        /** Queue a game state switch. */
84
        public void switchTo(Class<? extends BaseGameState> nextState, String param)
85
        {
86
                mParam = param;
87
                mNextStateClass = nextState;           
88
        }
89
 
90
        /** Switch to state specified by String - must be fully qualified Class name! */
91
        public void switchTo(String nextState, String param)
92
        {
93
                Class<? extends BaseGameState> nextStateClass = null;
94
 
95
                try
96
                {
97
                        //mNextStateClass = Class.forName(nextState);
98
                        nextStateClass = Class.forName(mDefaultPackage + "." + nextState).asSubclass(BaseGameState.class);
99
                }
100
                catch (ClassNotFoundException ex)
101
                {
102
                //      Gdx.app.log(Consts.LOG_TAG, "ClassNotFoundException when switching to " + mDefaultPackage + "." + nextState + ", trying without default package name");
103
 
104
                        /** Try without package name. */
105
                        try
106
                        {
107
                                nextStateClass = Class.forName(nextState).asSubclass(BaseGameState.class);
108
                        }
109
                        catch (ClassNotFoundException ex2)
110
                        {
111
                                Gdx.app.log(Consts.LOG_TAG, "ClassNotFoundException when switching to " + nextState);
112
                                return;
113
                        }
114
                }
115
 
116
                switchTo(nextStateClass, param);               
117
        }
118
 
119
        public BaseGameState createNextState(Class<? extends BaseGameState> newState)
120
        {
121
                BaseGameState result;
122
                try
123
                {
124
                        //mCurrentState = (BaseGameState)newState.newInstance();
125
                        result = (BaseGameState)newState.getDeclaredConstructor(Game.class).newInstance(getGame());
126
                }
127
                catch (NoSuchMethodException ex)
128
                {
129
                        Gdx.app.log(Consts.LOG_TAG, "NoSuchMethodException when switching to " + newState.toString());
130
                        return null;
131
                }
132
                catch (InvocationTargetException ex)
133
                {
134
                        Gdx.app.log(Consts.LOG_TAG, "InvocationTargetEception when switching to " + newState.toString());
135
                        return null;
136
                }
137
                catch (InstantiationException ex)
138
                {
139
                        Gdx.app.log(Consts.LOG_TAG, "InstantiationException when switching to " + newState.toString());
140
                        return null;
141
                }
142
                catch (IllegalAccessException ex)
143
                {
144
                        Gdx.app.log(Consts.LOG_TAG, "IllegalAccessException when switching to " + newState.toString());
145
                        return null;
146
                }
147
                return result;
148
        }
149
 
150
        /** Update the current game state (if one is running). */
151
        public void update(float deltaTime)
152
        {
153
                mStateModeTimer += deltaTime;
154
                switch (mStateMode)
155
                {
156
                case MODE_NORMAL:
157
                        updateNormal(deltaTime);
158
                        break;
159
                case MODE_FADEIN:
160
                        updateFadeIn(deltaTime);
161
                        break;
162
                case MODE_FADEOUT:
163
                        updateFadeOut(deltaTime);
164
                        break;
165
                case MODE_EXIT_STATE:
166
                        updateExitState(deltaTime);
167
                        if (mLoadingScreen != null)
168
                                mLoadingScreen.update(deltaTime);
169
                        break;
170
                case MODE_INIT_STATE:
171
                        updateInitState(deltaTime);
172
                        if (mLoadingScreen != null)
173
                                mLoadingScreen.update(deltaTime);
174
                        break;
175
                }              
176
        }
177
 
178
        public void switchState(StateMode nextStateMode)
179
        {
180
                mStateMode = nextStateMode;
181
                mStateModeTimer = 0.0f;
182
        }
183
 
184
        public void updateNormal(float deltaTime)
185
        {
186
                // check if state switch queued
187
                if (mNextStateClass != null)
188
                {
189
                        // if current state is null or doesn't want to fade out, switch directly
190
                        if ((mCurrentState != null) && (mCurrentState.doFadeOut()))
191
                        {
192
                                switchState(StateMode.MODE_FADEOUT);
193
                                updateFadeColor();
194
                        }
195
                        else
196
                                switchState(StateMode.MODE_EXIT_STATE);
197
                }
198
 
199
                if (mCurrentState != null)
200
                {
201
                        mCurrentState.update(deltaTime);
202
                }
203
        }
204
 
205
        public void updateFadeIn(float deltaTime)
206
        {
207
                if (mCurrentState != null)
208
                {
209
                        mCurrentState.updateFading(deltaTime);
210
                }
211
 
212
                if (mStateModeTimer > FADE_TIME)
213
                {
214
                        // after fade in, switch to normal state mode
215
                        switchState(StateMode.MODE_NORMAL);
216
                        return;
217
                }
218
                updateFadeColor();
219
        }
220
 
221
        public void updateFadeOut(float deltaTime)
222
        {
223
                if (mCurrentState != null)
224
                {
225
                        mCurrentState.updateFading(deltaTime);
226
                }
227
 
228
                if (mStateModeTimer > FADE_TIME)
229
                {
230
                        // switch to exiting current state
231
                        switchState(StateMode.MODE_EXIT_STATE);
232
                        return;
233
                }
234
                updateFadeColor();
235
        }
236
 
237
        public void updateInitState(float deltaTime)
238
        {
239
                // if current state is null, current state has not been created yet
240
                if (mCurrentState == null)
241
                {
242
                        if (mNextStateClass == null)
243
                                return;
244
 
245
                        mCurrentState = createNextState(mNextStateClass);
246
                        mNextStateClass = null;
247
 
248
                        // call asynchronous loading first.
249
                        if (mCurrentState != null)
250
                                mCurrentState.initAsync(mParam);
251
                }
252
                else
253
                {
254
                        // Current state was already been created, so wait for asynchronous loading to finish
255
                        if (getAssetManager().update())
256
                        {
857 chris 257
                                //Gdx.app.log("BLA", "DONE");
835 chris 258
                                // done loading, so call synchronous loading
259
                                mCurrentState.init(mParam);
260
                                getGame().updateInternalTimer();
261
 
262
                                // now finally switch
263
                                if ((mCurrentState != null) && (mCurrentState.doFadeIn()))
264
                                {
265
                                        switchState(StateMode.MODE_FADEIN);
266
                                        updateFadeColor();
267
                                }
268
                                else
269
                                        switchState(StateMode.MODE_NORMAL);
270
                        }
271
                }
272
        }
273
 
274
        public void updateExitState(float deltaTime)
275
        {
276
                if (mCurrentState != null)
277
                {
278
                        mCurrentState.exit();
279
                        mCurrentState = null;
280
                }
281
 
282
                switchState(StateMode.MODE_INIT_STATE);
283
        }
284
 
285
        public void updateFadeColor()
286
        {
287
                float r = 0.0f;
288
                float g = 0.0f;
289
                float b = 0.0f;
290
                float alpha = 0.0f;
291
 
292
                if (mStateMode == StateMode.MODE_FADEOUT)
293
                {
294
                        if (mCurrentState != null)
295
                        {
296
                                r = mCurrentState.getFadeOutColor().x;
297
                                g = mCurrentState.getFadeOutColor().y;
298
                                b = mCurrentState.getFadeOutColor().z;
299
                        }
300
                        alpha = MathUtil.clamp(mStateModeTimer / FADE_TIME, 0.0f, 1.0f);
301
                }
302
                else if (mStateMode == StateMode.MODE_FADEIN)
303
                {
304
                        if (mCurrentState != null)
305
                        {
306
                                r = mCurrentState.getFadeInColor().x;
307
                                g = mCurrentState.getFadeInColor().y;
308
                                b = mCurrentState.getFadeInColor().z;
309
                        }
310
                        alpha = 1.0f-MathUtil.clamp(mStateModeTimer / FADE_TIME, 0.0f, 1.0f);
311
                }
312
 
313
                mScreenFader.setFadeColor(r, g, b, alpha);
314
        }
315
 
316
        /** Render the current game state (if one is running). */
317
        public void render()
318
        {
319
                float r = 0;
320
                float g = 0;
321
                float b = 0;
322
                if (mCurrentState != null)
323
                {
324
                        r = mCurrentState.getFadeOutColor().x;
325
                        g = mCurrentState.getFadeOutColor().y;
326
                        b = mCurrentState.getFadeOutColor().z;
327
                }
328
 
329
                switch (mStateMode)
330
                {
331
                case MODE_NORMAL:
332
                        if (mCurrentState != null)
333
                                mCurrentState.render();
334
                        break;
335
                case MODE_FADEIN:
336
                case MODE_FADEOUT:
337
                        if (mCurrentState != null)
338
                                mCurrentState.render();
339
                        mScreenFader.render();
340
                        break;
341
                case MODE_EXIT_STATE:
342
                        // black out completely
343
                        mScreenFader.setFadeColor(r, g, b, 1.0f);
344
                        mScreenFader.render();
345
                        break;
346
                case MODE_INIT_STATE:
347
                        // render loading screen
348
                        if ((mCurrentState != null) && (mCurrentState.haveLoadingScreen()) && (mLoadingScreen != null))
349
                        {
350
                                // render loading screen
351
                                mLoadingScreen.render();
352
                        }
353
                        else
354
                        {
355
                                // no loading screen or not specified to use, so just render fade-in color in preparation
356
                                mScreenFader.setFadeColor(r, g, b, 1.0f);
357
                                mScreenFader.render();
358
                        }
359
                        break;
360
                }
361
        }
362
 
363
        /** Called when the surface properties changed. */
364
        public void onSurfaceChanged(int w, int h)
365
        {
366
                if (mCurrentState != null)
367
                {
368
                        mCurrentState.onSurfaceChanged(w, h);
369
                }
370
        }
371
 
372
        /** Called when resuming after pausing and initially. */
373
        public void onResume()
374
        {
375
                if (mCurrentState != null)
376
                {
377
                        mCurrentState.onResume();
378
                }
379
        }
380
 
381
        /** Called when the app is paused. */
382
        public void onPause()
383
        {
384
                if (mCurrentState != null)
385
                {
386
                        mCurrentState.onPause();
387
                }
388
        }
389
 
390
        // Getters/Setters==================================================================================
391
 
392
        /** Set the default package name. */
393
        public void setDefaultPackage(String defaultPackage) { mDefaultPackage = defaultPackage; }
394
 
395
        /** Get the last set parameter. */
396
        public String getCurrentParam() { return mParam; }
397
 
398
        /** Get the current state or null if no state is set. */
399
        public BaseGameState getCurrentState() { return mCurrentState; }
400
 
401
        /** Provide a loading screen implementation. */
402
        public final void setLoadingScreen(BaseLoadingScreen loadingScreen) { mLoadingScreen = loadingScreen; }
403
 
404
        /** Get the loading screen. */
405
        public final BaseLoadingScreen getLoadingScreen() { return mLoadingScreen; }
406
 
407
 
408
}
409
 
410