Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.game;

import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.gebauz.bauzoid.app.BauzoidApp;
import com.gebauz.bauzoid.app.Consts;
import com.gebauz.bauzoid.app.CustomServices;
import com.gebauz.bauzoid.app.Settings;
import com.gebauz.bauzoid.audio.Audio;
import com.gebauz.bauzoid.gamestates.GameStateManager;
import com.gebauz.bauzoid.graphics.Font;
import com.gebauz.bauzoid.graphics.FontCollection;
import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.spritex.AtlasDefinition;
import com.gebauz.bauzoid.graphics.spritex.AtlasSpriteAsyncLoader;
import com.gebauz.bauzoid.graphics.sprite.SpriteRegionDefinition;
import com.gebauz.bauzoid.graphics.sprite.SpriteRegionAsyncLoader;
import com.gebauz.bauzoid.input.Input;

/** Root object for the game. Manages game-global objects, acts as the root of the game graph, and kicks off update and render calls.
 *
 * This is the parent class for the following subsystems:
 * - GameStateManager: Root object for game states.
 * - Graphics: Root object for all graphics objects
 * - Audio: Root object for all audio objects
 * - ..
 *
 * It also offers convenient access to the Android application's Context
 *
 * It is implemented as a Generic, with T being the concrete implementation fo the CustomServices class for the app.
 */

public class Game
{
        // Embedded Types=======================================================================================
       
        /** Toggles debug mode and stepping mode - however, the client app must implement these functionalities. */
        public class BauzoidInputProcessor extends InputAdapter
        {
           @Override
           public boolean keyDown (int keycode)
           {
/*                 switch (keycode)
                   {
                   case com.badlogic.gdx.Input.Keys.BACK:
                   case com.badlogic.gdx.Input.Keys.D:
                           // toggle debug info
                           mEnableDebugInfo = !mEnableDebugInfo;
                           break;
                   case com.badlogic.gdx.Input.Keys.P:
                           // toggle debug pause mode
                           mEnableDebugStepperMode = !mEnableDebugStepperMode;
                           break;                          
                   case com.badlogic.gdx.Input.Keys.S:
                           // allow one step
                           mAllowStep = true;
                           break;
                   }*/

                   return false;
           }
        }          
       
        /** Interface to allow client apps to override aspects of the game. */
        public static interface IGameFactory
        {
                public abstract Input createInput(Game game);          
                public abstract Graphics createGraphics(Game game);
                public abstract Audio createAudio(Game game);  
                public abstract FontCollection createFontCollection(Game game);
        }      
       
        public static class DefaultGameFactory implements IGameFactory
        {
                @Override
                public Input createInput(Game game)
                {
                        return new Input(game);
                }

                @Override
                public Graphics createGraphics(Game game)
                {
                        return new Graphics(game);
                }

                @Override
                public Audio createAudio(Game game)
                {
                        return new Audio(game);
                }
               
                @Override
                public FontCollection createFontCollection(Game game)
                {
                        return new FontCollection(game);
                }
        }
       
        // Fields===============================================================================================
       
        private BauzoidApp mApp = null;
        private String mGameTitle = "BauzoidGame";
        private boolean mAdsEnabled = false;
        private GameStateManager mGameStateManager = null;
       
        private Graphics mGraphics = null;
        private Audio mAudio = null;
        private Input mInput = null;
        private FontCollection mFonts = null;
       
        private final long mRandomSeed = System.currentTimeMillis();
        //private final long mRandomSeed = 1367274339256L;
        private Random mRandomizer = new Random(mRandomSeed);
       
        private AssetManager mAssetManager = null;
       
        private Settings mSettings = null;
       
        private CustomServices mCustomServices = null;
       
        /** When true, allows game components to display debug information. */
        private boolean mEnableDebugInfo = false;
        private boolean mEnableDebugStepperMode = false;
        private boolean mAllowStep = false;

        private long mPreviousTime = 0;
        private int mFrameCount = 0;
        private float mFps = 0.0f;
        private float mRunTime = 0.0f;
        private float mDeltaTime = 0.0f;
       
        private IGameFactory mGameFactory = new DefaultGameFactory();
       
        // Methods==============================================================================================
       
        /** Constructor. */
        public Game(BauzoidApp app, String title, boolean adsEnabled, IGameFactory gameFactory)
        {
                Gdx.app.log(Consts.LOG_TAG, "Seed Used: " + mRandomSeed);
               
                mApp = app;
               
                // Set the context to use for engine exceptions
                mGameTitle = title;
                mAdsEnabled = adsEnabled;

                mGameStateManager = new GameStateManager(this);
               
                if (gameFactory != null)
                        mGameFactory = gameFactory;
               
                mGraphics = mGameFactory.createGraphics(this);
                mAudio = mGameFactory.createAudio(this);
                mInput = mGameFactory.createInput(this);
                mFonts = mGameFactory.createFontCollection(this);
               
                mSettings = new Settings();
               
                mAssetManager = new AssetManager();
               
                mPreviousTime = mApp.getSystemTimeMs();

                Gdx.input.setCatchBackKey(true);
               
                // install asynchronous loaders
                mAssetManager.setLoader(AtlasDefinition.class, new AtlasSpriteAsyncLoader(new InternalFileHandleResolver()));
                mAssetManager.setLoader(SpriteRegionDefinition.class, new SpriteRegionAsyncLoader(new InternalFileHandleResolver()));
        }
       
        /** Called for game-global initialization. */
        public void init()
        {
                mGraphics.init();
                mAudio.init();
                mInput.init();
                mFonts.init();
               
                mGameStateManager.init();
               
                mSettings.loadSettings(Gdx.files.internal("data/config.txt"));
               
                Gdx.input.setInputProcessor(new BauzoidInputProcessor());
        }
       
        /** Called for game-global destruction. */
        public void exit()
        {
                mGameStateManager.exit();
               
                mFonts.exit();
                mInput.exit();
                mAudio.exit();
                mGraphics.exit();
       
                if (mCustomServices != null)
                {
                        mCustomServices.exit();
                        mCustomServices = null;
                }
               
                if (mAssetManager != null)
                {
                        mAssetManager.dispose();
                        mAssetManager = null;
                }
        }
       
        /** Update game logic state. */
        public void update(float deltaTime)
        {
                mDeltaTime = deltaTime;
                mRunTime += deltaTime;
               
                if (mCustomServices != null)
                {
                        mCustomServices.update(deltaTime);
                }
               
                mGameStateManager.update(deltaTime);
                mAudio.update(deltaTime);
                mInput.update(deltaTime);
               
                updateFps(deltaTime);
               
                mAllowStep = false;
        }
       
        /** Update the internal timer so that the next deltaTime won't be too large. This is used for instance during GameState initialization when init() could take a long time. */
        public void updateInternalTimer()
        {
                mDeltaTime = mApp.updateInternalTimer();
                mRunTime += mDeltaTime;
        }
       
        public void updateFps(float deltaTime)
        {              
            long currentTime = getCurrentTimeMs();
            long timeInterval = currentTime - mPreviousTime;

            if(timeInterval > 1000)
            {
                // calculate the number of frames per second
                mFps = mFrameCount / (timeInterval / 1000.0f);
                mPreviousTime = currentTime;
                mFrameCount = 0;
            }
        }
       
        /** Render game. */
        public void render()
        {
                if (mCustomServices != null)
                {
                        mCustomServices.render();
                }
               
                mGameStateManager.render();
                mAudio.render();
                mInput.render();
               
                mFrameCount++;
        }
       
        /** Called when the surface dimensions have changed. */
        public void resize(int w, int h)
        {
                mGraphics.updateSurfaceDimensions(w, h);
                mInput.updateSurfaceDimensions(w, h);
                mGameStateManager.onSurfaceChanged(w, h);
        }
       
        /** Called when the OpenGL Context is about to be destroyed. */
        public void pause()
        {
                mGraphics.onSurfaceLost();
                mAudio.onPause();
                mInput.onPause();
                mGameStateManager.onPause();
        }
       
        /** Called when the OpenGL Context has been recreated after onSurfaceLost(). */
        public void resume()
        {
                mGraphics.onSurfaceRecreated();
                mAudio.onResume();
                mInput.onResume();
                mGameStateManager.onResume();
        }
       
        /** Install an app specific custom services. */
        public final void setCustomServices(CustomServices customServices)
        {
                if (mCustomServices != null)
                        mCustomServices.exit();
               
                mCustomServices = customServices;
               
                if (mCustomServices != null)
                        mCustomServices.init();
        }
       
        public float getRandomFloat(float min, float max)
        {
                return min + mRandomizer.nextFloat() * (max-min);
        }
       
        public int getRandomInt(int min, int max)
        {
                return min + mRandomizer.nextInt(max-min+1);
        }
       
        /** Returns -1 or 1 with a 50:50 chance. */
        public int getRandomSign()
        {
                int n = getRandomInt(0, 1);
                if (n == 1)
                        return -1;
                return 1;
        }
       
        public void showAds(boolean visible)
        {
                mApp.showAds(visible);
        }
       
        // Getters/Setters==================================================================================
       
        /** Get the main graphics object. */
        public final Graphics getGraphics() { return mGraphics; }
       
        /** Get the main audio object. */
        public final Audio getAudio() { return mAudio; }

        /** Get the main input object. */
        public final Input getInput() { return mInput; }
       
        /** Get the font collection. */
        public final FontCollection getFonts() { return mFonts; }
       
        /** Get a specific font. */
        public final Font getFont(String name) { return mFonts.getFont(name); }
       
        /** Get the app specific custom services. */
        public final CustomServices getCustomServices() { return mCustomServices; }
       
        /** Get the GameStateManager. */
        public final GameStateManager getGameStateManager() { return mGameStateManager; }

        /** Get the Randomizer. */
        public Random getRandomizer() { return mRandomizer; }
       
        /** Get the AssetManager. */
        public AssetManager getAssetManager() { return mAssetManager; }
       
        /** Get the Game Title. */
        public final String getGameTitle() { return mGameTitle; }
       
        /** Check if ads are enabled. */
        public final boolean areAdsEnabled() { return mAdsEnabled; }
       
        /** Set a settings object. */
        public final void setSettings(Settings settings) { mSettings = settings; }
       
        /** Get the settings object. */
        public final Settings getSettings() { return mSettings; }
       
        /** Get the current system time in milliseconds. */
        public final long getCurrentTimeMs() { return mApp.getSystemTimeMs(); }
       
        /** Get the time the game has run in seconds. Useful for sine/cosine stuffs and animating. */
        public final float getTime() { return mRunTime; }
       
        /** Get the frames per second. */
        public final float getFps() { return mFps; }
       
        /** Get seconds per frame. */
        public final float getFrameTime()
        {
                if (mFps == 0.0f)
                        return 0.0f;
                return (1/mFps);               
        }
       
        /** Get the last frame's delta time. */
        public final float getDeltaTime() { return mDeltaTime; }
       
        public boolean isDebugInfoEnabled() { return mEnableDebugInfo; }
        public void enableDebugInfo(boolean enableDebugInfo) { mEnableDebugInfo = enableDebugInfo; }
       
        public boolean isDebugStepperModeEnabled() { return mEnableDebugStepperMode; }
        public boolean stepNextFrame() { return mAllowStep; }
}