Subversion Repositories AndroidProjects

Rev

Rev 200 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.Bauzoid.gamestates;

import java.lang.reflect.InvocationTargetException;

import com.badlogic.gdx.Gdx;
import com.gebauz.Bauzoid.app.Consts;
import com.gebauz.Bauzoid.app.Game;
import com.gebauz.Bauzoid.app.GameObject;
import com.gebauz.Bauzoid.math.MathUtil;

/** Manages game state switching, updating, rendering, and initialization/destruction. */
public class GameStateManager extends GameObject
{
        static final float FADE_TIME = 1.0f;
       
        private enum StateMode
        {
                MODE_NORMAL,    // everything normal
                MODE_FADEIN,    // fade in
                MODE_FADEOUT    // fade out
        };
       
        private BaseGameState mCurrentState = null;
        private Class<?> mNextStateClass = null;
        private StateMode mStateMode = StateMode.MODE_NORMAL;
        private float mFadeTimer = 0.0f;
       
        //private SimpleGeometry mFadeOverlay = null;
       
        /** Constructor. */
        public GameStateManager(Game game)
        {
                super(game);           
        }
       
        /** Called when the GameStateManager should initially set up its internals. */
        public void init()
        {
               
        }
       
        /** Called when the GameStateManager should clean up. */
        public void exit()
        {
                if (mCurrentState != null)
                {
                        // reset everything
                       
                        mCurrentState.exit();
                        mCurrentState = null;
                       
                        mNextStateClass = null;
                        mStateMode = StateMode.MODE_NORMAL;
                        mFadeTimer = 0.0f;
                }
        }
       
        /** Queue a game state switch. */
        public void switchTo(Class<?> nextState)
        {
                if ((mCurrentState != null) && (mCurrentState.doFadeOut()))
                {
                        mStateMode = StateMode.MODE_FADEOUT;
                        mFadeTimer = 0.0f;
                }
               
                mNextStateClass = nextState;           
        }
       
        /** Switch to state specified by String - must be fully qualified Class name! */
        public void switchTo(String nextState)
        {
                try
                {
                        mNextStateClass = Class.forName(nextState);
                }
                catch (ClassNotFoundException ex)
                {
                        Gdx.app.log(Consts.LOG_TAG, "ClassNotFoundException when switching to " + nextState);
                }
        }
       
        /** Actually perform the switch. */
        private void performSwitch(Class<?> newState)
        {
                if (newState == null)
                {
                        return;
                }
               
                if (mCurrentState != null)
                {
                        mCurrentState.exit();
                        mCurrentState = null;
                }
               
                try
                {
                        //mCurrentState = (BaseGameState)newState.newInstance();
                        mCurrentState = (BaseGameState)newState.getDeclaredConstructor(Game.class).newInstance(getGame());
                }
                catch (NoSuchMethodException ex)
                {
                        Gdx.app.log(Consts.LOG_TAG, "NoSuchMethodException when switching to " + newState.toString());
                        return;
                }
                catch (InvocationTargetException ex)
                {
                        Gdx.app.log(Consts.LOG_TAG, "InvocationTargetEception when switching to " + newState.toString());
                        return;
                }
                catch (InstantiationException ex)
                {
                        Gdx.app.log(Consts.LOG_TAG, "InstantiationException when switching to " + newState.toString());
                        return;
                }
                catch (IllegalAccessException ex)
                {
                        Gdx.app.log(Consts.LOG_TAG, "IllegalAccessException when switching to " + newState.toString());
                        return;
                }
               
                if (mCurrentState != null)
                {
                        mCurrentState.init();
                        //mCurrentState.onSurfaceChanged(GLUtil.getInstance().getWidth(), GLUtil.getInstance().getHeight());
                       
                        if (mCurrentState.doFadeIn())
                        {
                                mStateMode = StateMode.MODE_FADEIN;
                                mFadeTimer = 0.0f;
                        }
                }
        }

        /** Update the current game state (if one is running). */
        public void update(float deltaTime)
        {
                if (mStateMode != StateMode.MODE_NORMAL)
                {
                        mFadeTimer += deltaTime;
                        if (mFadeTimer > FADE_TIME)
                        {
                                mStateMode = StateMode.MODE_NORMAL;
                        }
                }
               
                if ((mStateMode == StateMode.MODE_NORMAL) && (mNextStateClass != null))
                {
                        // perform the actual switch
                        performSwitch(mNextStateClass);
                        mNextStateClass = null;
                }              
               
                if ((mCurrentState != null) && (mStateMode == StateMode.MODE_NORMAL))
                {
                        mCurrentState.update(deltaTime);
                }
               
                float alpha = MathUtil.clamp(mFadeTimer / FADE_TIME, 0.0f, 1.0f);
                if (mStateMode == StateMode.MODE_FADEOUT)
                        alpha = 1.0f - alpha;
       
                // TODO: do it with shader!
/*              Mesh.AttributeArray colors = new Mesh.AttributeArray(Mesh.COLOR_ELEMENTS_COUNT * mFadeOverlay.getColorCount());
                for (int i = 0; i < mFadeOverlay.getColorCount(); i++)
                {
                        colors.fill(alpha, alpha, alpha, 1.0f);
                        //colors.fill(1.0f, 1.0f, 1.0f, alpha);
                }
                mFadeOverlay.setColors(colors.getAttributeArray());*/

        }

        /** Render the current game state (if one is running). */
        public void render()
        {
                if (mCurrentState != null)
                {                      
                        mCurrentState.render();
                }              
               
                if (mStateMode != StateMode.MODE_NORMAL)
                {
/*                      gl.glMatrixMode(GL10.GL_PROJECTION);
                        gl.glLoadIdentity();
                        gl.glOrthof(0, GameConsts.VIRTUAL_SCREEN_WIDTH-1.0f, GameConsts.VIRTUAL_SCREEN_HEIGHT-1.0f, 0, 0, 1);
                        gl.glMatrixMode(GL10.GL_MODELVIEW);
                        gl.glLoadIdentity();
                       

                        if (mFadeTimer <= GameConsts.FADE_TIME)
                        {
                                RenderStates rs = GLUtil.getRenderStates();
                                rs.blending.setEnabled(true);
                                rs.blending.setBlendingMode(BlendingMode.MULTIPLY);
                                rs.depthTest.setEnabled(false);
                                rs.culling.setEnabled(false);
                                rs.getTextureStage(0).bindTexture(null, true);
                                rs.activate();
                                mFadeOverlay.render();
                                rs.deactivate();
                        }*/

                }
        }
       
        /** Called when the surface properties changed. */
        public void onSurfaceChanged(int w, int h)
        {
                if (mCurrentState != null)
                {
                        mCurrentState.onSurfaceChanged(w, h);
                }
        }
       
        /** Called when resuming after pausing and initially. */
        public void onResume()
        {
               
        }
       
        /** Called when the app is paused. */
        public void onPause()
        {
               
        }
       
}