package com.siondream.core; import java.util.Locale; import ashley.core.Engine; import aurelienribon.tweenengine.Tween; import aurelienribon.tweenengine.TweenManager; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.InputMultiplexer; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.physics.box2d.World; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.Logger; import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.viewport.ExtendViewport; import com.badlogic.gdx.utils.viewport.Viewport; import com.siondream.core.assets.Assets; import com.siondream.core.entity.components.TransformComponent; import com.siondream.core.entity.factory.ComponentReaders.ColorComponentReader; import com.siondream.core.entity.factory.ComponentReaders.FontComponentReader; import com.siondream.core.entity.factory.ComponentReaders.MapComponentReader; import com.siondream.core.entity.factory.ComponentReaders.OverridePhysicsComponentReader; import com.siondream.core.entity.factory.ComponentReaders.ParticleComponentReader; import com.siondream.core.entity.factory.ComponentReaders.PhysicsComponentReader; import com.siondream.core.entity.factory.ComponentReaders.ShaderComponentReader; import com.siondream.core.entity.factory.ComponentReaders.SpineComponentReader; import com.siondream.core.entity.factory.ComponentReaders.SpriteComponentReader; import com.siondream.core.entity.factory.ComponentReaders.StateComponentReader; import com.siondream.core.entity.factory.ComponentReaders.TextureComponentReader; import com.siondream.core.entity.factory.ComponentReaders.TransformComponentReader; import com.siondream.core.entity.factory.EntityFactory; import com.siondream.core.entity.systems.PhysicsSystem; import com.siondream.core.physics.CategoryBitsManager; import com.siondream.core.physics.CollisionHandler; import com.siondream.core.tweeners.ActorTweener; import com.siondream.core.tweeners.CameraTweener; import com.siondream.core.tweeners.TransformTweener; public class SionGame extends Game implements InputProcessor { private final String TAG = "SionGame"; private Logger logger; private ObjectMap<Class<? extends SionScreen>, SionScreen> screens; private SionScreen nextScreen; private SionScreen currentScreen; private InputMultiplexer multiplexer; private ExtendViewport viewport; private OrthographicCamera camera; private ExtendViewport uiViewport; private OrthographicCamera uiCamera; private Assets assets; private Engine engine; private Stage stage; private TweenManager tweenManager; private LanguageManager languageManager; private World world; private double accumulator; private double currentTime; private ParticleEffectPools particlePools; private ShaderManager shaderManager; private EntityFactory entityFactory; private CategoryBitsManager categoryBitsManager; private CollisionHandler collisionHandler; @Override public void create() { Env.init(this); logger = new Logger(TAG, Env.debugLevel); logger.info("initialising"); categoryBitsManager = new CategoryBitsManager(); assets = new Assets("data/config/assets.json"); assets.loadGroup("base"); assets.finishLoading(); screens = new ObjectMap<Class<? extends SionScreen>, SionScreen>(); nextScreen = null; currentScreen = null; camera = new OrthographicCamera(); viewport = new ExtendViewport(800 * Env.pixelsToMetres, 600 * Env.pixelsToMetres, 1280 * Env.pixelsToMetres, 720 * Env.pixelsToMetres, camera); uiCamera = new OrthographicCamera(); uiViewport = new ExtendViewport(800, 600, 1280, 720, uiCamera); tweenManager = new TweenManager(); Tween.registerAccessor(OrthographicCamera.class, new CameraTweener()); Tween.registerAccessor(Actor.class, new ActorTweener()); Tween.registerAccessor(TransformComponent.class, new TransformTweener()); Tween.setCombinedAttributesLimit(4); world = new World(Env.gravity, Env.doSleep); collisionHandler = new CollisionHandler(); world.setContactListener(collisionHandler); accumulator = 0.0; currentTime = TimeUtils.millis() / 1000.0; engine = new Engine(); stage = new Stage(); stage.setViewport(uiViewport); multiplexer = new InputMultiplexer(); Gdx.input.setInputProcessor(multiplexer); Gdx.input.setCatchBackKey(Env.catchBack); Gdx.input.setCatchMenuKey(Env.catchMenu); multiplexer.addProcessor(this); languageManager = new LanguageManager("data/lang", Locale.getDefault().getLanguage()); particlePools = new ParticleEffectPools(); shaderManager = new ShaderManager(); entityFactory = new EntityFactory(); entityFactory.registerReader(new ColorComponentReader()); entityFactory.registerReader(new FontComponentReader()); entityFactory.registerReader(new MapComponentReader()); entityFactory.registerReader(new OverridePhysicsComponentReader()); entityFactory.registerReader(new ParticleComponentReader()); entityFactory.registerReader(new PhysicsComponentReader()); entityFactory.registerReader(new ShaderComponentReader()); entityFactory.registerReader(new SpineComponentReader()); entityFactory.registerReader(new SpriteComponentReader()); entityFactory.registerReader(new StateComponentReader()); entityFactory.registerReader(new TextureComponentReader()); entityFactory.registerReader(new TransformComponentReader()); } @Override public void dispose() { logger.info("shutting down"); assets.dispose(); world.dispose(); stage.dispose(); if (currentScreen != null) { currentScreen.dispose(); } } @Override public void render() { double newTime = TimeUtils.millis() / 1000.0; double frameTime = Math.min(newTime - currentTime, 0.25); float deltaTime = (float)frameTime; currentTime = newTime; if (currentScreen != null) { currentScreen.render(deltaTime); } tweenManager.update(deltaTime); accumulator += frameTime; PhysicsSystem physics = engine.getSystem(PhysicsSystem.class); while (accumulator >= Env.physicsDeltaTime) { if (physics != null) { physics.update(Env.physicsDeltaTime); } world.step(Env.physicsDeltaTime, Env.velocityIterations, Env.positionIterations); accumulator -= Env.physicsDeltaTime; if (physics != null) { physics.interpolate(Env.physicsDeltaTime, (float)(accumulator / Env.physicsDeltaTime)); } } engine.update(deltaTime); stage.act(deltaTime); performScreenChange(); } @Override public void resize(int width, int height) { if (currentScreen != null) { currentScreen.resize(width, height); } } @Override public void pause() { if (currentScreen != null) { currentScreen.pause(); } } @Override public void resume() { if (currentScreen != null) { currentScreen.resume(); } } protected void addScreen(SionScreen screen) { screens.put(screen.getClass(), screen); } public <T extends SionScreen> T getScreen(Class<T> type) { return type.cast(screens.get(type)); } @Override public void setScreen(Screen screen) { logger.error("method not supported"); } public void setScreen(Class<? extends SionScreen> type) { SionScreen screen = screens.get(type); if (screen != null) { nextScreen = screen; } else { logger.error("invalid screen " + type.getName()); } } public Assets getAssets() { return assets; } public OrthographicCamera getCamera() { return camera; } public Viewport getViewport() { return viewport; } public OrthographicCamera getUICamera() { return uiCamera; } public Viewport getUIViewport() { return uiViewport; } public World getWorld() { return world; } public Stage getStage() { return stage; } public TweenManager getTweenManager() { return tweenManager; } public Engine getEngine() { return engine; } public LanguageManager getLang() { return languageManager; } public InputMultiplexer getInputMultiplexer() { return multiplexer; } public ParticleEffectPools getParticlePools() { return particlePools; } public ShaderManager getShaderManager() { return shaderManager; } public EntityFactory getEntityFactory() { return entityFactory; } public CategoryBitsManager getCategoryBitsManager() { return categoryBitsManager; } public CollisionHandler getCollisionHandler() { return collisionHandler; } private void performScreenChange() { if (nextScreen != null) { logger.info("switching to screen " + screens.findKey(nextScreen, false)); multiplexer.removeProcessor(currentScreen); setScreenInternal(nextScreen); multiplexer.addProcessor(currentScreen); nextScreen = null; } } private void setScreenInternal(SionScreen screen) { super.setScreen(screen); currentScreen = screen; } @Override public boolean keyDown(int keycode) { if (Env.debug) { if (keycode == Keys.F1) { Env.init(this); } } return stage.keyDown(keycode); } @Override public boolean keyUp(int keycode) { return stage.keyUp(keycode); } @Override public boolean keyTyped(char character) { return stage.keyTyped(character); } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { return stage.touchDown(screenX, screenY, pointer, button); } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { return stage.touchUp(screenX, screenY, pointer, button); } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { return stage.touchDragged(screenX, screenY, pointer); } @Override public boolean mouseMoved(int screenX, int screenY) { return stage.mouseMoved(screenX, screenY); } @Override public boolean scrolled(int amount) { return stage.scrolled(amount); } }