/* * Copyright (c) 2012. HappyDroids LLC, All rights reserved. */ package com.happydroids.droidtowers; import aurelienribon.tweenengine.Tween; import com.badlogic.gdx.Application; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.happydroids.droidtowers.achievements.AchievementEngine; import com.happydroids.droidtowers.actions.ActionManager; import com.happydroids.droidtowers.actions.TimeDelayedAction; import com.happydroids.droidtowers.audio.GameSoundController; import com.happydroids.droidtowers.controllers.PathSearchManager; import com.happydroids.droidtowers.entities.GameObject; import com.happydroids.droidtowers.events.InGamePurchaseReceiver; import com.happydroids.droidtowers.gamestate.server.TowerGameService; import com.happydroids.droidtowers.generators.NameGenerator; import com.happydroids.droidtowers.gui.FontManager; import com.happydroids.droidtowers.gui.WidgetAccessor; import com.happydroids.droidtowers.input.*; import com.happydroids.droidtowers.platform.Display; import com.happydroids.droidtowers.scenes.ApplicationResumeScene; import com.happydroids.droidtowers.scenes.LaunchUriScene; import com.happydroids.droidtowers.scenes.MainMenuScene; import com.happydroids.droidtowers.scenes.Scene; import com.happydroids.droidtowers.scenes.components.SceneManager; import com.happydroids.droidtowers.server.MovieServer; import com.happydroids.droidtowers.tasks.MigrateExistingGamesTask; import com.happydroids.droidtowers.tasks.SyncCloudGamesTask; import com.happydroids.droidtowers.tween.GameObjectAccessor; import com.happydroids.droidtowers.tween.TweenSystem; import com.happydroids.droidtowers.types.*; import com.happydroids.platform.Platform; import com.happydroids.security.SecurePreferences; import com.happydroids.utils.BackgroundTask; import static com.badlogic.gdx.Application.ApplicationType.*; import static com.happydroids.HappyDroidConsts.DEBUG; import static com.happydroids.HappyDroidConsts.DISPLAY_DEBUG_INFO; public class DroidTowersGame implements ApplicationListener, BackgroundTask.PostExecuteManager { private static final String TAG = DroidTowersGame.class.getSimpleName(); private SpriteBatch spriteBatch; private static Stage rootUiStage; private SpriteBatch spriteBatchFBO; private FrameBuffer frameBuffer; private static GameSoundController soundController; private final Runnable afterInitRunnable; private final StringBuilder debugInfo; private float timeUntilDebugInfoUpdate; public DroidTowersGame(Runnable afterInitRunnable) { this.afterInitRunnable = afterInitRunnable; debugInfo = new StringBuilder(); TowerGameService.instance(); } public void create() { if (afterInitRunnable != null) { afterInitRunnable.run(); } Thread.currentThread().setUncaughtExceptionHandler(Platform.getUncaughtExceptionHandler()); Gdx.app.error("lifecycle", "create"); if (Gdx.app.getType().equals(Desktop)) { SecurePreferences displayPrefs = TowerGameService.instance().getPreferences(); if (displayPrefs.contains("width") && displayPrefs.contains("height") && displayPrefs.contains("fullscreen")) { Gdx.graphics .setDisplayMode(displayPrefs.getInteger("width"), displayPrefs.getInteger("height"), displayPrefs.getBoolean("fullscreen")); } else { Gdx.graphics.setDisplayMode(960, 540, false); } } Display.setup(); BackgroundTask.setPostExecuteManager(this); BackgroundTask.setUncaughtExceptionHandler(Platform.uncaughtExceptionHandler); TowerGameService.setInstance(new TowerGameService()); if (Gdx.graphics.isGL20Available() && Gdx.app.getType().equals(Android)) { if (Display.isXHDPIMode()) { // float displayScalar = 0.75f; // frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, (int) (Display.getWidth() * displayScalar), (int) (Display.getHeight() * displayScalar), true); // spriteBatchFBO = new SpriteBatch(); } else if (Display.isInCompatibilityMode()) { frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, Display.getWidth(), Display.getHeight(), true); spriteBatchFBO = new SpriteBatch(); } } if (DEBUG) { Gdx.app.error("DEBUG", "Debug mode is enabled!"); Gdx.app.setLogLevel(Application.LOG_DEBUG); } else { Gdx.app.setLogLevel(Application.LOG_ERROR); } TowerAssetManager.assetManager(); ActionManager.instance().addAction(new TimeDelayedAction(1f) { @Override public void run() { soundController = new GameSoundController(); markToRemove(); } }); new MigrateExistingGamesTask().run(); TowerGameService.instance().afterDeviceIdentification(new Runnable() { @Override public void run() { if (!TowerGameService.instance().isAuthenticated()) { return; } new SyncCloudGamesTask().run(); } }); Platform.getPurchaseManager().events().register(new InGamePurchaseReceiver()); NameGenerator.initialize(); RoomTypeFactory.instance(); CommercialTypeFactory.instance(); ServiceRoomTypeFactory.instance(); ElevatorTypeFactory.instance(); StairTypeFactory.instance(); AchievementEngine.instance(); Tween.setCombinedAttributesLimit(4); Tween.registerAccessor(CameraController.class, new CameraControllerAccessor()); Tween.registerAccessor(GameObject.class, new GameObjectAccessor()); Tween.registerAccessor(Actor.class, new WidgetAccessor()); spriteBatch = new SpriteBatch(); rootUiStage = new Stage(Display.getWidth(), Display.getHeight(), false, spriteBatch); Gdx.input.setInputProcessor(InputSystem.instance()); InputSystem.instance().addInputProcessor(rootUiStage, 0); if (DEBUG) { InputSystem.instance().addInputProcessor(new DebugInputAdapter(), 1000); } InputSystem.instance().addInputProcessor(new QuitGameInputAdapter(), 1000000); Scene.setSpriteBatch(spriteBatch); Gdx.app.postRunnable(new Runnable() { @Override public void run() { if (Platform.protocolHandler != null && Platform.protocolHandler.hasUri()) { SceneManager.changeScene(LaunchUriScene.class, Platform.protocolHandler.consumeUri()); } else { SceneManager.changeScene(MainMenuScene.class); } if (!Gdx.app.getType().equals(Applet)) { Platform.getConnectionMonitor().withConnection(new Runnable() { @Override public void run() { new RegisterDeviceTask().run(); } }); } } }); } public void render() { Gdx.gl.glClearColor(0.48f, 0.729f, 0.870f, 1.0f); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); Gdx.gl.glEnable(GL10.GL_TEXTURE_2D); float deltaTime = Gdx.graphics.getDeltaTime(); SceneManager.activeScene().getCamera().update(); ActionManager.instance().update(deltaTime); InputSystem.instance().update(deltaTime); PathSearchManager.instance().update(deltaTime); TweenSystem.manager().update((int) (deltaTime * 1000 * SceneManager.activeScene().getTimeMultiplier())); if (soundController != null) { soundController.update(deltaTime); } spriteBatch.setProjectionMatrix(SceneManager.activeScene().getCamera().combined); if (frameBuffer != null) { frameBuffer.begin(); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); SceneManager.activeScene().render(deltaTime); frameBuffer.end(); spriteBatchFBO.begin(); spriteBatchFBO.draw(frameBuffer.getColorBufferTexture(), 0, 0, Gdx.graphics.getWidth(), Gdx.graphics .getHeight(), 0, 0, 1, 1); spriteBatchFBO.end(); } else { SceneManager.activeScene().render(deltaTime); } SceneManager.activeScene().getStage().act(deltaTime); SceneManager.activeScene().getStage().draw(); if (rootUiStage.getActors().size > 0) { rootUiStage.act(deltaTime); rootUiStage.draw(); } //noinspection PointlessBooleanExpression if (DEBUG && DISPLAY_DEBUG_INFO) { Table.drawDebug(SceneManager.activeScene().getStage()); Table.drawDebug(rootUiStage); float javaHeapInBytes = Gdx.app.getJavaHeap() / TowerConsts.ONE_MEGABYTE; float nativeHeapInBytes = Gdx.app.getNativeHeap() / TowerConsts.ONE_MEGABYTE; timeUntilDebugInfoUpdate -= deltaTime; if (timeUntilDebugInfoUpdate <= 0f) { timeUntilDebugInfoUpdate = 3f; debugInfo.delete(0, debugInfo.length()); debugInfo.append("fps: "); debugInfo.append(Gdx.graphics.getFramesPerSecond()); debugInfo.append("\nmem: (java "); debugInfo.append((int) javaHeapInBytes); debugInfo.append("Mb, heap: "); debugInfo.append((int) nativeHeapInBytes); debugInfo.append("Mb, gpu: "); debugInfo.append((int) TowerAssetManager.assetManager().getMemoryInMegabytes()); debugInfo.append("Mb)"); debugInfo.append(" psm: "); debugInfo.append(PathSearchManager.instance().queueLength()); } spriteBatch.begin(); BitmapFont font = FontManager.Roboto12.getFont(); font.setColor(Color.BLACK); font.drawMultiLine(spriteBatch, debugInfo, 6, 35); font.setColor(Color.CYAN); font.drawMultiLine(spriteBatch, debugInfo, 5, 36); font.setColor(Color.WHITE); spriteBatch.end(); } } public void resize(int width, int height) { Gdx.app.log("lifecycle", "resizing!"); if (SceneManager.activeScene() != null) { SceneManager.activeScene().getCamera().viewportWidth = width; SceneManager.activeScene().getCamera().viewportHeight = height; SceneManager.activeScene().getSpriteBatch().getProjectionMatrix().setToOrtho2D(0, 0, width, height); Gdx.gl.glViewport(0, 0, width, height); spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, width, height); } } public void pause() { Gdx.app.error("lifecycle", "pausing!"); SceneManager.activeScene().pause(); } public void resume() { Gdx.app.error("lifecycle", "resuming!"); FontManager.resetAll(); SceneManager.pushScene(ApplicationResumeScene.class); } public void dispose() { Gdx.app.error("lifecycle", "dispose"); SceneManager.activeScene().dispose(); rootUiStage = null; SceneManager.dispose(); spriteBatch.dispose(); Platform.getConnectionMonitor().dispose(); PathSearchManager.instance().dispose(); BackgroundTask.dispose(); MovieServer.dispose(); TowerAssetManager.dispose(); FontManager.resetAll(); Platform.dispose(); System.exit(0); } public static Stage getRootUiStage() { return rootUiStage; } public static GameSoundController getSoundController() { return soundController; } public void postRunnable(Runnable runnable) { Gdx.app.postRunnable(runnable); } }