From 99236420d11704c39c2e9fb67f063574b7252156 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Jun 2014 11:32:02 -0430 Subject: [PATCH] Fixed device orientation calculation. Other assorted fixes. --- src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java | 10 +- .../nxtar/components/FadeEffectComponent.java | 57 +++ .../nxtar/states/AutomaticActionState.java | 432 ++++++++++++++++++ .../ciens/ccg/nxtar/states/InGameState.java | 144 ++---- .../nxtar/systems/BombGamePlayerSystem.java | 37 +- .../systems/FadeEffectRenderingSystem.java | 7 +- .../systems/MarkerPositioningSystem.java | 29 +- .../ciens/ccg/nxtar/utils/GameSettings.java | 37 ++ src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java | 37 +- 9 files changed, 650 insertions(+), 140 deletions(-) create mode 100644 src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java diff --git a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java index 9ee47ef..da7bbfc 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java +++ b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java @@ -238,7 +238,15 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this); else states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this); - states[game_states_t.IN_GAME.getValue()] = new InGameState(this); + + try{ + states[game_states_t.IN_GAME.getValue()] = new InGameState(this); + }catch(IllegalStateException e){ + Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state: " + e.getMessage()); + Gdx.app.exit(); + return; + } + states[game_states_t.CALIBRATION.getValue()] = new CameraCalibrationState(this); // Register controller listeners. diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java index 1490354..ba0fabf 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java +++ b/src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java @@ -20,12 +20,19 @@ import aurelienribon.tweenengine.TweenEquations; import aurelienribon.tweenengine.primitives.MutableFloat; import com.artemis.Component; +import com.badlogic.gdx.graphics.Color; public class FadeEffectComponent extends Component{ private MutableFloat alpha; private Tween fadeIn; private Tween fadeOut; + public Color color; + /** + *

Creates a fade to/from white depending on the parameter.

+ * + * @param fadeIn True to create a fade FROM white, false for a fade TO white. + */ public FadeEffectComponent(boolean fadeIn){ if(fadeIn){ this.alpha = new MutableFloat(1.0f); @@ -36,12 +43,50 @@ public class FadeEffectComponent extends Component{ this.fadeOut = Tween.to(alpha, 0, 2.5f).target(1.0f).ease(TweenEquations.easeInQuint); this.fadeIn = null; } + color = new Color(Color.WHITE); } + /** + *

Creates a fade effect with the desired parameters.

+ * + * @param fadeIn True to create a fade FROM color, false for a fade TO color. + * @param color The color of the effect. + */ + public FadeEffectComponent(boolean fadeIn, Color color){ + this(fadeIn); + this.color.set(color); + } + + /** + *

Creates a fade out effect of the desired color.

+ * + * @param color The color of the effect. + */ + public FadeEffectComponent(Color color){ + this(false, color); + } + + /** + *

Creates a white fade out effect.

+ */ + public FadeEffectComponent(){ + this(false); + } + + /** + *

The current transparency of the effect.

+ * + * @return The transparency. + */ public float getFloatValue(){ return alpha.floatValue(); } + /** + *

Interpolates the transparency of the effect by the given delta time in seconds.

+ * + * @param delta + */ public void update(float delta){ if(fadeIn != null) fadeIn.update(delta); @@ -50,6 +95,9 @@ public class FadeEffectComponent extends Component{ fadeOut.update(delta); } + /** + *

Initializes the effect.

+ */ public void startEffect(){ if(fadeIn != null) fadeIn.start(); @@ -58,14 +106,23 @@ public class FadeEffectComponent extends Component{ fadeOut.start(); } + /** + * @return True if the effect has been initialized. False otherwise. + */ public boolean isEffectStarted(){ return fadeIn != null ? fadeIn.isStarted() : fadeOut.isStarted(); } + /** + * @return True if this effect is a fade in. False if it is a fade out. + */ public boolean isEffectFadeIn(){ return fadeIn != null; } + /** + * @return True if the effect's interpolation is over. False otherwise. + */ public boolean isEffectFinished(){ return fadeIn != null ? fadeIn.isFinished() : fadeOut.isFinished(); } diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java new file mode 100644 index 0000000..73b9354 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ve.ucv.ciens.ccg.nxtar.states; + +import ve.ucv.ciens.ccg.nxtar.NxtARCore; +import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; +import ve.ucv.ciens.ccg.nxtar.graphics.CustomPerspectiveCamera; +import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; +import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; +import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem; +import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem; +import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem; +import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; +import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.RobotArmPositioningSystem; +import ve.ucv.ciens.ccg.nxtar.utils.GameSettings; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; +import ve.ucv.ciens.ccg.nxtar.utils.Utils; + +import com.artemis.World; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.controllers.Controller; +import com.badlogic.gdx.controllers.mappings.Ouya; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.Texture.TextureFilter; +import com.badlogic.gdx.graphics.Texture.TextureWrap; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.graphics.glutils.FrameBuffer; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; + +public class AutomaticActionState extends BaseState{ + private static final String TAG = "IN_GAME_STATE"; + private static final String CLASS_NAME = AutomaticActionState.class.getSimpleName(); + private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg"; + private static final float NEAR = 0.01f; + private static final float FAR = 100.0f; + + // Background related fields. + private Sprite background; + private float uScaling[]; + private Texture backgroundTexture; + private ShaderProgram backgroundShader; + + // 3D rendering fields. + private ModelBatch modelBatch; + private FrameBuffer frameBuffer; + private Sprite frameBufferSprite; + + // Game related fields. + private World gameWorld; + private MarkerRenderingSystem markerRenderingSystem; + private ObjectRenderingSystem objectRenderingSystem; + private RobotArmPositioningSystem robotArmPositioningSystem; + private FadeEffectRenderingSystem fadeEffectRenderingSystem; + + // Cameras. + private OrthographicCamera unitaryOrthographicCamera; + private OrthographicCamera pixelPerfectOrthographicCamera; + private CustomPerspectiveCamera perspectiveCamera; + + // Video stream graphics. + private Texture videoFrameTexture; + private Sprite renderableVideoFrame; + private Pixmap videoFrame; + + // Button touch helper fields. + private boolean[] buttonsTouched; + private int[] buttonPointers; + private boolean[] gamepadButtonPressed; + + // Monitors. + private VideoFrameMonitor frameMonitor; + // private MotorEventQueue queue; + // private SensorReportThread sensorThread; + + public AutomaticActionState(final NxtARCore core){ + this.core = core; + frameMonitor = VideoFrameMonitor.getInstance(); + // queue = MotorEventQueue.getInstance(); + // sensorThread = SensorReportThread.getInstance(); + + // Set up rendering fields; + videoFrame = null; + + // Set up the cameras. + pixelPerfectOrthographicCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + unitaryOrthographicCamera = new OrthographicCamera(1.0f, Gdx.graphics.getHeight() / Gdx.graphics.getWidth()); + + // Set up input handling support fields. + win2world = new Vector3(0.0f, 0.0f, 0.0f); + touchPointWorldCoords = new Vector2(); + + buttonsTouched = new boolean[1]; + buttonsTouched[0] = false; + + buttonPointers = new int[1]; + buttonPointers[0] = -1; + + gamepadButtonPressed = new boolean[1]; + gamepadButtonPressed[0] = false; + + // Set up the background. + backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png")); + backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); + backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); + background = new Sprite(backgroundTexture); + background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2)); + + // Set up the shader. + backgroundShader = new ShaderProgram(Gdx.files.internal(BACKGROUND_SHADER_PATH + "_vert.glsl"), Gdx.files.internal(BACKGROUND_SHADER_PATH + "_frag.glsl")); + if(!backgroundShader.isCompiled()){ + Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the background shader."); + Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog()); + backgroundShader = null; + } + + uScaling = new float[2]; + uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; + uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; + + // Set up the 3D rendering. + modelBatch = new ModelBatch(); + frameBuffer = null; + perspectiveCamera = null; + frameBufferSprite = null; + + // Set up the game world. + gameWorld = GameSettings.getGameWorld(); + + robotArmPositioningSystem = new RobotArmPositioningSystem(); + markerRenderingSystem = new MarkerRenderingSystem(modelBatch); + objectRenderingSystem = new ObjectRenderingSystem(modelBatch); + fadeEffectRenderingSystem = new FadeEffectRenderingSystem(); + + gameWorld.setSystem(new MarkerPositioningSystem()); + gameWorld.setSystem(robotArmPositioningSystem, Ouya.runningOnOuya); + gameWorld.setSystem(new GeometrySystem()); + gameWorld.setSystem(new AnimationSystem()); + gameWorld.setSystem(new CollisionDetectionSystem()); + gameWorld.setSystem(GameSettings.getGameLogicSystem()); + gameWorld.setSystem(markerRenderingSystem, true); + gameWorld.setSystem(objectRenderingSystem, true); + gameWorld.setSystem(fadeEffectRenderingSystem, true); + + gameWorld.initialize(); + } + + /*;;;;;;;;;;;;;;;;;;;;;; + ; BASE STATE METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;*/ + + @Override + public void render(float delta){ + int w, h; + byte[] frame; + MarkerData data; + TextureRegion region; + float focalPointX, focalPointY, cameraCenterX, cameraCenterY; + + // Clear the screen. + Gdx.gl.glClearColor(1, 1, 1, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + // Render the background. + core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined); + core.batch.begin();{ + if(backgroundShader != null){ + core.batch.setShader(backgroundShader); + backgroundShader.setUniform2fv("u_scaling", uScaling, 0, 2); + } + background.draw(core.batch); + if(backgroundShader != null) core.batch.setShader(null); + }core.batch.end(); + + // Fetch the current video frame. + frame = frameMonitor.getCurrentFrame(); + w = frameMonitor.getFrameDimensions().getWidth(); + h = frameMonitor.getFrameDimensions().getHeight(); + + // Create the 3D perspective camera and the frame buffer object if they don't exist. + if(perspectiveCamera == null && frameBuffer == null){ + frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true); + frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); + + perspectiveCamera = new CustomPerspectiveCamera(67, w, h); + perspectiveCamera.translate(0.0f, 0.0f, 0.0f); + perspectiveCamera.near = NEAR; + perspectiveCamera.far = FAR; + perspectiveCamera.lookAt(0.0f, 0.0f, -1.0f); + perspectiveCamera.update(); + } + + // Attempt to find the markers in the current video frame. + data = core.cvProc.findMarkersInFrame(frame); + + // If a valid frame was fetched. + if(data != null && data.outFrame != null){ + // Set the camera to the correct projection. + focalPointX = core.cvProc.getFocalPointX(); + focalPointY = core.cvProc.getFocalPointY(); + cameraCenterX = core.cvProc.getCameraCenterX(); + cameraCenterY = core.cvProc.getCameraCenterY(); + perspectiveCamera.setCustomARProjectionMatrix(focalPointX, focalPointY, cameraCenterX, cameraCenterY, NEAR, FAR, w, h); + perspectiveCamera.update(perspectiveCamera.projection); + + // Update the game state. + gameWorld.setDelta(Gdx.graphics.getDeltaTime() * 1000); + gameWorld.getSystem(MarkerPositioningSystem.class).setMarkerData(data); + gameWorld.process(); + + // Decode the video frame. + videoFrame = new Pixmap(data.outFrame, 0, w * h); + videoFrameTexture = new Texture(videoFrame); + videoFrameTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); + videoFrame.dispose(); + + // Convert the decoded frame into a renderable texture. + region = new TextureRegion(videoFrameTexture, 0, 0, w, h); + if(renderableVideoFrame == null) + renderableVideoFrame = new Sprite(region); + else + renderableVideoFrame.setRegion(region); + renderableVideoFrame.setOrigin(renderableVideoFrame.getWidth() / 2, renderableVideoFrame.getHeight() / 2); + renderableVideoFrame.setPosition(0, 0); + + // Set the 3D frame buffer for rendering. + frameBuffer.begin();{ + // Set OpenGL state. + Gdx.gl.glClearColor(0, 0, 0, 0); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); + Gdx.gl.glDisable(GL20.GL_TEXTURE_2D); + + // Call rendering systems. + markerRenderingSystem.begin(perspectiveCamera); + markerRenderingSystem.process(); + markerRenderingSystem.end(); + }frameBuffer.end(); + + // Set the frame buffer object texture to a renderable sprite. + region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight()); + region.flip(false, true); + if(frameBufferSprite == null) + frameBufferSprite = new Sprite(region); + else + frameBufferSprite.setRegion(region); + frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2); + frameBufferSprite.setPosition(0, 0); + + // Set the position and orientation of the renderable video frame and the frame buffer. + if(!Ouya.runningOnOuya){ + renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() ); + renderableVideoFrame.rotate90(true); + renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, 0.5f - renderableVideoFrame.getHeight()); + + frameBufferSprite.setSize(1.0f, frameBufferSprite.getHeight() / frameBufferSprite.getWidth() ); + frameBufferSprite.rotate90(true); + frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight()); + }else{ + float xSize = Gdx.graphics.getHeight() * (w / h); + renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); + renderableVideoFrame.rotate90(true); + renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2); + + frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); + frameBufferSprite.rotate90(true); + frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2); + } + + // Set the correct camera for the device. + if(!Ouya.runningOnOuya){ + core.batch.setProjectionMatrix(unitaryOrthographicCamera.combined); + }else{ + core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined); + } + + // Render the video frame and the frame buffer. + core.batch.begin();{ + renderableVideoFrame.draw(core.batch); + frameBufferSprite.draw(core.batch); + }core.batch.end(); + + // Clear the video frame from memory. + videoFrameTexture.dispose(); + } + + data = null; + } + + @Override + public void dispose(){ + if(modelBatch != null) + modelBatch.dispose(); + + if(videoFrameTexture != null) + videoFrameTexture.dispose(); + + if(backgroundTexture != null) + backgroundTexture.dispose(); + + if(backgroundShader != null) + backgroundShader.dispose(); + + if(frameBuffer != null) + frameBuffer.dispose(); + + fadeEffectRenderingSystem.dispose(); + } + + /*;;;;;;;;;;;;;;;;;; + ; HELPER METHODS ; + ;;;;;;;;;;;;;;;;;;*/ + + @Override + public void onStateSet(){ + stateActive = true; + Gdx.input.setInputProcessor(this); + Gdx.input.setCatchBackKey(true); + Gdx.input.setCatchMenuKey(true); + } + + @Override + public void onStateUnset(){ + stateActive = false; + Gdx.input.setInputProcessor(null); + Gdx.input.setCatchBackKey(false); + Gdx.input.setCatchMenuKey(false); + } + + /*;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; INPUT PROCESSOR METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;*/ + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button){ + if(!Ouya.runningOnOuya){ + win2world.set(screenX, screenY, 0.0f); + unitaryOrthographicCamera.unproject(win2world); + touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight()); + } + + return false; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button){ + if(!Ouya.runningOnOuya){ + win2world.set(screenX, screenY, 0.0f); + unitaryOrthographicCamera.unproject(win2world); + touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight()); + } + + return false; + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer){ + if(!Ouya.runningOnOuya){ + win2world.set(screenX, screenY, 0.0f); + unitaryOrthographicCamera.unproject(win2world); + touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight()); + } + + return false; + } + + @Override + public boolean keyDown(int keycode){ + if(keycode == Input.Keys.BACK){ + core.nextState = game_states_t.MAIN_MENU; + return true; + } + + return false; + } + + /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; CONTROLLER LISTENER METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/ + + @Override + public boolean buttonDown(Controller controller, int buttonCode){ + if(stateActive){ + Gdx.app.log(TAG, CLASS_NAME + ".buttonDown() :: " + controller.getName() + " :: " + Integer.toString(buttonCode)); + + if(buttonCode == Ouya.BUTTON_O){ + + } + + return true; + }else{ + return false; + } + } + + @Override + public boolean buttonUp(Controller controller, int buttonCode){ + if(stateActive){ + Gdx.app.log(TAG, CLASS_NAME + ".buttonDown() :: " + controller.getName() + " :: " + Integer.toString(buttonCode)); + + if(buttonCode == Ouya.BUTTON_O){ } + + return true; + }else{ + return false; + } + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index bbdd025..157028f 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -27,10 +27,7 @@ import ve.ucv.ciens.ccg.nxtar.input.UserInput; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue; import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; -import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem; -import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem; import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem; -import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; @@ -94,9 +91,6 @@ public class InGameState extends BaseState{ private ModelBatch modelBatch; private FrameBuffer frameBuffer; private Sprite frameBufferSprite; - // private FrameBuffer robotArmFrameBuffer; - // private Sprite robotArmFrameBufferSprite; - // private ShaderProgram alphaShader; // Game related fields. private World gameWorld; @@ -126,7 +120,7 @@ public class InGameState extends BaseState{ private Texture armControlButtonTexture; private Texture correctAngleLedOnTexture; private Texture correctAngleLedOffTexture; - private Texture crossSectionFloorTexture; + private Texture orientationSliderTexture; // Gui renderable sprites. private Sprite motorAButton; @@ -144,9 +138,7 @@ public class InGameState extends BaseState{ private Sprite armControlButton; private Sprite correctAngleLedOnSprite; private Sprite correctAngleLedOffSprite; - private Sprite crossSectionFloorLed; - private Sprite normalFloorLed; - private Sprite itemNearbyFloorLed; + private Sprite orientationSlider; // Button touch helper fields. private boolean[] buttonsTouched; @@ -156,14 +148,12 @@ public class InGameState extends BaseState{ // Monitors. private VideoFrameMonitor frameMonitor; private MotorEventQueue queue; - // private SensorReportThread sensorThread; - public InGameState(final NxtARCore core){ + public InGameState(final NxtARCore core) throws IllegalStateException{ this.core = core; frameMonitor = VideoFrameMonitor.getInstance(); queue = MotorEventQueue.getInstance(); controlMode = robot_control_mode_t.WHEEL_CONTROL; - // sensorThread = SensorReportThread.getInstance(); // Set up rendering fields; videoFrame = null; @@ -225,61 +215,26 @@ public class InGameState extends BaseState{ uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; - // Set up the alpha shader. - // alphaShader = new ShaderProgram(Gdx.files.internal(ALPHA_SHADER_PREFIX + "_vert.glsl"), Gdx.files.internal(ALPHA_SHADER_PREFIX + "_frag.glsl")); - // if(!alphaShader.isCompiled()){ - // Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the alpha shader."); - // Gdx.app.error(TAG, CLASS_NAME + alphaShader.getLog()); - // alphaShader = null; - // } - // Set up the 3D rendering. modelBatch = new ModelBatch(); frameBuffer = null; perspectiveCamera = null; frameBufferSprite = null; - // robotArmFrameBuffer = null; - // robotArmFrameBufferSprite = null; - - // Set up floor leds and possibly the buttons. - correctAngleLedOnTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Green.png")); - correctAngleLedOffTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Red.png")); - crossSectionFloorTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Cyan.png")); - - crossSectionFloorLed = new Sprite(crossSectionFloorTexture); - normalFloorLed = new Sprite(correctAngleLedOffTexture); - itemNearbyFloorLed = new Sprite(correctAngleLedOnTexture); - - crossSectionFloorLed.setSize(crossSectionFloorLed.getWidth() * 0.25f, crossSectionFloorLed.getHeight() * 0.25f); - normalFloorLed.setSize(normalFloorLed.getWidth() * 0.25f, normalFloorLed.getHeight() * 0.25f); - itemNearbyFloorLed.setSize(itemNearbyFloorLed.getWidth() * 0.25f, itemNearbyFloorLed.getHeight() * 0.25f); - - crossSectionFloorLed.setPosition(-(crossSectionFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - crossSectionFloorLed.getHeight() - 5); - normalFloorLed.setPosition(-(normalFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - normalFloorLed.getHeight() - 5); - itemNearbyFloorLed.setPosition(-(itemNearbyFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - itemNearbyFloorLed.getHeight() - 5); + // Set up he buttons. if(!Ouya.runningOnOuya) setUpButtons(); // Set up the game world. gameWorld = GameSettings.getGameWorld(); - robotArmPositioningSystem = new RobotArmPositioningSystem(); - markerRenderingSystem = new MarkerRenderingSystem(modelBatch); - objectRenderingSystem = new ObjectRenderingSystem(modelBatch); - fadeEffectRenderingSystem = new FadeEffectRenderingSystem(); + robotArmPositioningSystem = gameWorld.getSystem(RobotArmPositioningSystem.class); + markerRenderingSystem = gameWorld.getSystem(MarkerRenderingSystem.class); + objectRenderingSystem = gameWorld.getSystem(ObjectRenderingSystem.class); + fadeEffectRenderingSystem = gameWorld.getSystem(FadeEffectRenderingSystem.class); - gameWorld.setSystem(new MarkerPositioningSystem()); - gameWorld.setSystem(robotArmPositioningSystem, Ouya.runningOnOuya); - gameWorld.setSystem(new GeometrySystem()); - gameWorld.setSystem(new AnimationSystem()); - gameWorld.setSystem(new CollisionDetectionSystem()); - gameWorld.setSystem(GameSettings.getGameLogicSystem()); - gameWorld.setSystem(markerRenderingSystem, true); - gameWorld.setSystem(objectRenderingSystem, true); - gameWorld.setSystem(fadeEffectRenderingSystem, true); - - gameWorld.initialize(); + if(robotArmPositioningSystem == null || markerRenderingSystem == null || objectRenderingSystem == null || fadeEffectRenderingSystem == null) + throw new IllegalStateException("One or more essential systems are null."); } /*;;;;;;;;;;;;;;;;;;;;;; @@ -288,7 +243,10 @@ public class InGameState extends BaseState{ @Override public void render(float delta){ + final float MIN_SLIDER_X = correctAngleLedOnSprite != null ? -(Utils.getScreenWidth() / 2) + 5 + correctAngleLedOnSprite.getWidth() : -(Utils.getScreenWidth() / 2) + 5; + final float MAX_SLIDER_X = correctAngleLedOnSprite != null ? (Utils.getScreenWidth() / 2) - 5 - correctAngleLedOnSprite.getWidth(): (Utils.getScreenWidth() / 2) - 5; int w, h; + float t, xSliderPos; byte[] frame; MarkerData data; TextureRegion region; @@ -319,9 +277,6 @@ public class InGameState extends BaseState{ frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true); frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); - // robotArmFrameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true); - // robotArmFrameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); - perspectiveCamera = new CustomPerspectiveCamera(67, w, h); perspectiveCamera.translate(0.0f, 0.0f, 0.0f); perspectiveCamera.near = NEAR; @@ -382,18 +337,6 @@ public class InGameState extends BaseState{ } }frameBuffer.end(); - // robotArmFrameBuffer.begin();{ - // // Set OpenGL state. - // Gdx.gl.glClearColor(0, 0, 0, 0); - // Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - // Gdx.gl.glDisable(GL20.GL_TEXTURE_2D); - // - // // Call rendering systems. - // objectRenderingSystem.begin(perspectiveCamera); - // objectRenderingSystem.process(); - // objectRenderingSystem.end(); - // }robotArmFrameBuffer.end(); - // Set the frame buffer object texture to a renderable sprite. region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight()); region.flip(false, true); @@ -404,16 +347,6 @@ public class InGameState extends BaseState{ frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2); frameBufferSprite.setPosition(0, 0); - // Set the other frame buffer object texture to a renderable sprite. - // region = new TextureRegion(robotArmFrameBuffer.getColorBufferTexture(), 0, 0, robotArmFrameBuffer.getWidth(), robotArmFrameBuffer.getHeight()); - // region.flip(false, true); - // if(robotArmFrameBufferSprite == null) - // robotArmFrameBufferSprite = new Sprite(region); - // else - // robotArmFrameBufferSprite.setRegion(region); - // robotArmFrameBufferSprite.setOrigin(robotArmFrameBuffer.getWidth() / 2, robotArmFrameBuffer.getHeight() / 2); - // robotArmFrameBufferSprite.setPosition(0, 0); - // Set the position and orientation of the renderable video frame and the frame buffer. if(!Ouya.runningOnOuya){ renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() ); @@ -424,9 +357,6 @@ public class InGameState extends BaseState{ frameBufferSprite.rotate90(true); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight()); - // robotArmFrameBufferSprite.setSize(1.0f, robotArmFrameBufferSprite.getHeight() / robotArmFrameBufferSprite.getWidth() ); - // robotArmFrameBufferSprite.rotate90(true); - // robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, 0.5f - robotArmFrameBufferSprite.getHeight()); }else{ float xSize = Gdx.graphics.getHeight() * (w / h); renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); @@ -436,10 +366,6 @@ public class InGameState extends BaseState{ frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); frameBufferSprite.rotate90(true); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2); - - // robotArmFrameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN); - // robotArmFrameBufferSprite.rotate90(true); - // robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, -robotArmFrameBufferSprite.getHeight() / 2); } // Set the correct camera for the device. @@ -453,16 +379,6 @@ public class InGameState extends BaseState{ core.batch.begin();{ renderableVideoFrame.draw(core.batch); frameBufferSprite.draw(core.batch); - - // Render the robot arm only when in the corresponding control mode. Always render it on the OUYA. - // if(controlMode.getValue() == robot_control_mode_t.ARM_CONTROL.getValue() || Ouya.runningOnOuya){ - // if(alphaShader != null){ - // core.batch.setShader(alphaShader); - // } - // robotArmFrameBufferSprite.draw(core.batch); - // if(alphaShader != null) core.batch.setShader(null); - // } - }core.batch.end(); // Clear the video frame from memory. @@ -497,13 +413,21 @@ public class InGameState extends BaseState{ headCButton.draw(core.batch); // Draw device rotation led. - if(Utils.isDeviceRollValid() && Math.abs(Gdx.input.getRoll()) < ProjectConstants.MAX_ABS_ROLL){ - correctAngleLedOnSprite.draw(core.batch); + if(Utils.isDeviceRollValid()){ + if(Math.abs(Gdx.input.getRoll()) < ProjectConstants.MAX_ABS_ROLL) + correctAngleLedOnSprite.draw(core.batch); + else + correctAngleLedOffSprite.draw(core.batch); + + t = (Gdx.input.getRoll() + 60.0f) / 120.0f; + xSliderPos = (MIN_SLIDER_X * t) + (MAX_SLIDER_X * (1.0f - t)); + xSliderPos = xSliderPos < MIN_SLIDER_X ? MIN_SLIDER_X : (xSliderPos > MAX_SLIDER_X ? MAX_SLIDER_X : xSliderPos); + orientationSlider.setPosition(xSliderPos, orientationSlider.getY()); + orientationSlider.draw(core.batch); }else{ correctAngleLedOffSprite.draw(core.batch); + orientationSlider.draw(core.batch); } - - // TODO: Draw rotation slider. }core.batch.end(); } @@ -544,8 +468,8 @@ public class InGameState extends BaseState{ if(backgroundTexture != null) backgroundTexture.dispose(); - if(crossSectionFloorTexture != null) - crossSectionFloorTexture.dispose(); + if(orientationSliderTexture != null) + orientationSliderTexture.dispose(); if(backgroundShader != null) backgroundShader.dispose(); @@ -553,16 +477,11 @@ public class InGameState extends BaseState{ if(frameBuffer != null) frameBuffer.dispose(); - // if(robotArmFrameBuffer != null) - // robotArmFrameBuffer.dispose(); - if(correctAngleLedOffTexture != null) correctAngleLedOffTexture.dispose(); if(correctAngleLedOnTexture != null) correctAngleLedOnTexture.dispose(); - - fadeEffectRenderingSystem.dispose(); } /*;;;;;;;;;;;;;;;;;; @@ -657,6 +576,9 @@ public class InGameState extends BaseState{ armControlButton.setPosition(-(armControlButton.getWidth() / 2), headCButton.getY() - headCButton.getHeight() - 15); // Set up the correct angle leds. + correctAngleLedOnTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Green.png")); + correctAngleLedOffTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Red.png")); + correctAngleLedOnSprite = new Sprite(correctAngleLedOnTexture); correctAngleLedOffSprite = new Sprite(correctAngleLedOffTexture); @@ -665,6 +587,12 @@ public class InGameState extends BaseState{ correctAngleLedOnSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOnSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOnSprite.getHeight() - 5); correctAngleLedOffSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOffSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOffSprite.getHeight() - 5); + + // Set up orientation slider. + orientationSliderTexture = new Texture(Gdx.files.internal("data/gfx/gui/slider_black.png")); + orientationSlider = new Sprite(orientationSliderTexture); + orientationSlider.setSize(orientationSlider.getWidth() * 0.25f, orientationSlider.getHeight() * 0.25f); + orientationSlider.setPosition(-(orientationSlider.getWidth() / 2), (Utils.getScreenHeight() / 2) - orientationSlider.getHeight() - 5); } /*;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/BombGamePlayerSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/BombGamePlayerSystem.java index e8cee15..db2a7cc 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/BombGamePlayerSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/BombGamePlayerSystem.java @@ -18,22 +18,47 @@ package ve.ucv.ciens.ccg.nxtar.systems; import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.components.BombGamePlayerComponent; import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator; +import ve.ucv.ciens.ccg.nxtar.utils.Utils; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.annotations.Mapper; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.Disposable; -public class BombGamePlayerSystem extends PlayerSystemBase{ +public class BombGamePlayerSystem extends PlayerSystemBase implements Disposable{ + private static final float HEART_Y_POS = (Utils.getScreenHeight() / 2) - 69; @Mapper ComponentMapper playerMapper; + private SpriteBatch batch; + private Texture heartTexture; + private Sprite heart; + public BombGamePlayerSystem(NxtARCore core){ super(BombGamePlayerComponent.class, core); + batch = new SpriteBatch(); + heartTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_heart_1.png")); + heart = new Sprite(heartTexture); + heart.setSize(heart.getWidth() * 0.5f, heart.getHeight() * 0.5f); } @Override protected void process(Entity e) { + float heartXPos; BombGamePlayerComponent player = playerMapper.get(e); + // Render remaining lives. + heartXPos = -(Utils.getScreenWidth() / 2) + 5; + for(int i = 0; i < player.lives; ++i){ + heart.setPosition(heartXPos, HEART_Y_POS); + heart.draw(batch); + heartXPos += heart.getWidth() + 5; + } + + // Check ending conditions. if(player.lives == 0){ player.gameFinished = true; player.victory = false; @@ -42,7 +67,17 @@ public class BombGamePlayerSystem extends PlayerSystemBase{ player.victory = true; } + // If met ending conditions then end the game. if(player.gameFinished) finishGame(player.victory); } + + @Override + public void dispose() { + if(batch != null) + batch.dispose(); + + if(heartTexture != null) + heartTexture.dispose(); + } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/FadeEffectRenderingSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/FadeEffectRenderingSystem.java index 32b49bd..3b5741a 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/FadeEffectRenderingSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/FadeEffectRenderingSystem.java @@ -45,11 +45,16 @@ public class FadeEffectRenderingSystem extends EntityProcessingSystem implements @Override protected void process(Entity e) { + float r, g, b; FadeEffectComponent fade = fadeMapper.get(e); + r = fade.color.r; + g = fade.color.g; + b = fade.color.b; + this.batch.setProjectionMatrix(this.camera.combined); this.batch.begin();{ - this.batch.setColor(1, 1, 1, fade.getFloatValue()); + this.batch.setColor(r, g, b, fade.getFloatValue()); this.batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2)); this.batch.setColor(1, 1, 1, 1); }this.batch.end(); diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java index 126b437..8f71a94 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java @@ -26,10 +26,6 @@ import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.annotations.Mapper; import com.artemis.systems.EntityProcessingSystem; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Matrix3; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; public class MarkerPositioningSystem extends EntityProcessingSystem { @Mapper ComponentMapper markerMapper; @@ -37,18 +33,12 @@ public class MarkerPositioningSystem extends EntityProcessingSystem { @Mapper ComponentMapper visibilityMapper; private MarkerData markers; - private Quaternion qAux; - private Matrix4 correctedRotation; - private Matrix3 mAux; @SuppressWarnings("unchecked") public MarkerPositioningSystem(){ super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, VisibilityComponent.class)); markers = null; - qAux = new Quaternion(); - mAux = new Matrix3(); - correctedRotation = new Matrix4(); } public void setMarkerData(MarkerData markers){ @@ -71,25 +61,8 @@ public class MarkerPositioningSystem extends EntityProcessingSystem { for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ if(markers.markerCodes[i] != 1){ if(markers.markerCodes[i] == marker.code){ - - qAux.setFromMatrix(markers.rotationMatrices[i]).nor(); - - if(Math.abs(qAux.getRoll()) > 10.0f){ -// qAux.setEulerAngles(qAux.getYaw(), qAux.getPitch(), 0.0f); -// qAux.toMatrix(correctedRotation.val); -// mAux.set(correctedRotation); - mAux.set(markers.rotationMatrices[i]); - - Gdx.app.log("ROTATION", "YAW : " + Float.toString(qAux.getYaw())); - Gdx.app.log("ROTATION", "PITCH: " + Float.toString(qAux.getPitch())); - Gdx.app.log("ROTATION", "ROLL : " + Float.toString(qAux.getRoll())); - Gdx.app.log("ROTATION", "------------------------------------------"); - }else{ - mAux.set(markers.rotationMatrices[i]); - } - geometry.position.set(markers.translationVectors[i]); - geometry.rotation.set(mAux); + geometry.rotation.set(markers.rotationMatrices[i]); visibility.visible = true; break; }else{ diff --git a/src/ve/ucv/ciens/ccg/nxtar/utils/GameSettings.java b/src/ve/ucv/ciens/ccg/nxtar/utils/GameSettings.java index 9af2342..94fe904 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/utils/GameSettings.java +++ b/src/ve/ucv/ciens/ccg/nxtar/utils/GameSettings.java @@ -18,21 +18,38 @@ package ve.ucv.ciens.ccg.nxtar.utils; import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator; import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase; +import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem; import ve.ucv.ciens.ccg.nxtar.systems.BombGameLogicSystem; +import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem; +import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.GameLogicSystemBase; +import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem; +import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; +import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.RobotArmPositioningSystem; +import com.artemis.EntitySystem; import com.artemis.World; import com.artemis.managers.GroupManager; +import com.artemis.utils.ImmutableBag; +import com.badlogic.gdx.controllers.mappings.Ouya; +import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.utils.Disposable; public abstract class GameSettings{ private static EntityCreatorBase entityCreator = null; private static GameLogicSystemBase gameLogicSystem = null; private static World gameWorld = null; + private static ModelBatch modelBatch = null; public static void initGameSettings(NxtARCore core) throws IllegalArgumentException{ if(core == null) throw new IllegalArgumentException("Core is null."); + if(modelBatch == null) + modelBatch = new ModelBatch(); + if(getGameWorld() == null){ gameWorld = new World(); gameWorld.setManager(new GroupManager()); @@ -46,9 +63,29 @@ public abstract class GameSettings{ if(getGameLogicSystem() == null) gameLogicSystem = new BombGameLogicSystem(); + + gameWorld.setSystem(new MarkerPositioningSystem()); + gameWorld.setSystem(new RobotArmPositioningSystem(), Ouya.runningOnOuya); + gameWorld.setSystem(new GeometrySystem()); + gameWorld.setSystem(new AnimationSystem()); + gameWorld.setSystem(new CollisionDetectionSystem()); + gameWorld.setSystem(gameLogicSystem); + gameWorld.setSystem(new MarkerRenderingSystem(modelBatch), true); + gameWorld.setSystem(new ObjectRenderingSystem(modelBatch), true); + gameWorld.setSystem(new FadeEffectRenderingSystem(), true); + + gameWorld.initialize(); } public static void clearGameSettings(){ + ImmutableBag systems = gameWorld.getSystems(); + + for(int i = 0; i < systems.size(); i++){ + if(systems.get(i) instanceof Disposable){ + ((Disposable)systems.get(i)).dispose(); + } + } + entityCreator.dispose(); entityCreator = null; gameLogicSystem = null; diff --git a/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java b/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java index 8509427..137fd52 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java +++ b/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java @@ -19,23 +19,58 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Peripheral; import com.badlogic.gdx.math.Vector3; +/** + * Assorted common auxiliary functions. + */ public abstract class Utils{ + private static final float MIN_PITCH = -80.0f; + private static final float MAX_PITCH = 5.0f; + private static final float MIN_AZIMUTH = -155.0f; + private static final float MAX_AZIMUTH = -40.0f; + + /** + *

Converts a libGDX {@link Vector3} to a String representation form easy logging.

+ * + * @param v The vector to convert. + * @return A string representation of the form "(v.x, v.y, v.z)". + */ public static String vector2String(Vector3 v){ return "(" + Float.toString(v.x) + ", " + Float.toString(v.y) + ", " + Float.toString(v.z) + ")"; } + /** + * @return The width of the screen accounting for screen overscan. + */ public static int getScreenWidth(){ return (int)(Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN); } + /** + * @return The height of the screen accounting for screen overscan. + */ public static int getScreenHeight(){ return (int)(Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN); } + /** + *

Checks if the device's orientation is available and wihtin some arbitrary ranges.

+ * + * @return True if the device can detect it's orientation and it's within range. False otherwise. + */ public static boolean isDeviceRollValid(){ boolean rollValid = Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer) && Gdx.input.isPeripheralAvailable(Peripheral.Compass); + float azimuth, pitch; - // TODO: Check device orientation for limits. + if(rollValid){ + azimuth = Gdx.input.getAzimuth(); + pitch = Gdx.input.getPitch(); + + if(pitch < MIN_PITCH || pitch > MAX_PITCH) + rollValid = false; + + if(rollValid && (azimuth < MIN_AZIMUTH || azimuth > MAX_AZIMUTH)) + rollValid = false; + } return rollValid; }