diff --git a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java index db77ca5..43d562c 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java +++ b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java @@ -24,6 +24,7 @@ import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread; import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread; import ve.ucv.ciens.ccg.nxtar.network.VideoStreamingThread; import ve.ucv.ciens.ccg.nxtar.states.AutomaticActionState; +import ve.ucv.ciens.ccg.nxtar.states.AutomaticActionSummaryState; import ve.ucv.ciens.ccg.nxtar.states.BaseState; import ve.ucv.ciens.ccg.nxtar.states.CameraCalibrationState; import ve.ucv.ciens.ccg.nxtar.states.InGameState; @@ -75,7 +76,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ * Valid game states. */ public enum game_states_t { - MAIN_MENU(0), IN_GAME(1), CALIBRATION(2), AUTOMATIC_ACTION(3); + MAIN_MENU(0), IN_GAME(1), CALIBRATION(2), AUTOMATIC_ACTION(3), SUMMARY(4); private int value; @@ -88,7 +89,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ } public static int getNumStates(){ - return 4; + return 5; } }; @@ -256,25 +257,35 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ // Create the state objects. states = new BaseState[game_states_t.getNumStates()]; - if(Ouya.runningOnOuya) - states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this); - else - states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this); try{ - states[game_states_t.IN_GAME.getValue()] = new InGameState(this); - }catch(IllegalStateException e){ - Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state in IN_GAME_STATE: " + e.getMessage()); - Gdx.app.exit(); - return; - } + if(Ouya.runningOnOuya) + 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.CALIBRATION.getValue()] = new CameraCalibrationState(this); + try{ + states[game_states_t.IN_GAME.getValue()] = new InGameState(this); + }catch(IllegalStateException e){ + Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state in IN_GAME_STATE: ", e); + Gdx.app.exit(); + return; + } - try{ - states[game_states_t.AUTOMATIC_ACTION.getValue()] = new AutomaticActionState(this); - }catch(IllegalStateException e){ - Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state in AUTOMATIC_ACTION_STATE: " + e.getMessage()); + states[game_states_t.CALIBRATION.getValue()] = new CameraCalibrationState(this); + + try{ + states[game_states_t.AUTOMATIC_ACTION.getValue()] = new AutomaticActionState(this); + }catch(IllegalStateException e){ + Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state in AUTOMATIC_ACTION_STATE: ", e); + Gdx.app.exit(); + return; + } + + states[game_states_t.SUMMARY.getValue()] = new AutomaticActionSummaryState(this); + + }catch(IllegalArgumentException e){ + Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal argument caught creating states: ", e); Gdx.app.exit(); return; } @@ -285,8 +296,8 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ } // Set up the overlay font. - overlayX = -(Utils.getScreenWidth() / 2) + 10; - overlayY = (Utils.getScreenHeight() / 2) - 10; + overlayX = -(Utils.getScreenWidthWithOverscan() / 2) + 10; + overlayY = (Utils.getScreenHeightWithOverscan() / 2) - 10; font = new BitmapFont(); font.setColor(1.0f, 1.0f, 0.0f, 1.0f); @@ -428,21 +439,23 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ } /** - *

Pause a currently running thread. Pausing an already paused thread is a - * no op.

+ *

Pauses the video streaming and the current state.

*/ public void pause(){ if(videoThread != null) videoThread.pause(); + + states[currState.getValue()].pause(); } /** - *

Resume a currently paused thread. Resuming an already resumed thread is a - * no op.

+ *

Resumes the video streaming and the current state.

*/ public void resume(){ if(videoThread != null) videoThread.play(); + + states[currState.getValue()].resume(); } /** @@ -473,7 +486,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ batch.dispose(); font.dispose(); - GameGlobals.clearGameSettings(); + GameGlobals.dispose(); } /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionPerformerBase.java b/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionPerformerBase.java index 13f12ed..cf60a8d 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionPerformerBase.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionPerformerBase.java @@ -18,6 +18,10 @@ package ve.ucv.ciens.ccg.nxtar.game; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; public abstract class AutomaticActionPerformerBase { + public abstract class AutomaticActionSummary{ + public abstract void reset(); + } + public enum automatic_action_t{ NO_ACTION, GO_FORWARD, @@ -34,6 +38,8 @@ public abstract class AutomaticActionPerformerBase { STOP_LOOKING; } - public abstract boolean performAutomaticAction(int lightSensorReading, MarkerData markers); - public abstract automatic_action_t getNextAction(); + public abstract boolean performAutomaticAction(int lightSensorReading, MarkerData markers); + public abstract automatic_action_t getNextAction(); + public abstract AutomaticActionSummary getSummary(); + public abstract void reset(); } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionSummaryOverlayBase.java b/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionSummaryOverlayBase.java new file mode 100644 index 0000000..949edf4 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/game/AutomaticActionSummaryOverlayBase.java @@ -0,0 +1,33 @@ +/* + * 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.game; + +import ve.ucv.ciens.ccg.nxtar.game.AutomaticActionPerformerBase.AutomaticActionSummary; + +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.Disposable; + +/** + *

Base class for summary screens. Just renders a summary overlay.

+ */ +public abstract class AutomaticActionSummaryOverlayBase implements Disposable{ + /** + *

Renders the overlay.

+ * + * @param batch The {@link SpriteBatch} to use for rendering. + */ + public abstract void render(SpriteBatch batch, AutomaticActionSummary summary); +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/GameGlobals.java b/src/ve/ucv/ciens/ccg/nxtar/game/GameGlobals.java index 5f5c3ff..96e57e1 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/GameGlobals.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/GameGlobals.java @@ -36,11 +36,12 @@ import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.utils.Disposable; public abstract class GameGlobals{ - private static EntityCreatorBase entityCreator = null; - private static GameLogicSystemBase gameLogicSystem = null; - private static World gameWorld = null; - private static ModelBatch modelBatch = null; - private static AutomaticActionPerformerBase automaticActionPerformer = null; + private static EntityCreatorBase entityCreator = null; + private static GameLogicSystemBase gameLogicSystem = null; + private static World gameWorld = null; + private static ModelBatch modelBatch = null; + private static AutomaticActionPerformerBase automaticActionPerformer = null; + private static AutomaticActionSummaryOverlayBase automaticActionSummaryOverlay = null; public static void initGameSettings(NxtARCore core) throws IllegalArgumentException, InstantiationException, IllegalAccessException{ if(core == null) @@ -49,12 +50,12 @@ public abstract class GameGlobals{ if(modelBatch == null) modelBatch = new ModelBatch(); - if(getGameWorld() == null){ + if(gameWorld == null){ gameWorld = new World(); gameWorld.setManager(new GroupManager()); } - if(getEntityCreator() == null){ + if(entityCreator == null){ try { entityCreator = (EntityCreatorBase) ScenarioImplementation.entityCreatorClass.newInstance(); } catch (InstantiationException e) { @@ -68,7 +69,7 @@ public abstract class GameGlobals{ entityCreator.setCore(core); } - if(getGameLogicSystem() == null){ + if(gameLogicSystem == null){ try { gameLogicSystem = (GameLogicSystemBase) ScenarioImplementation.gameLogicSystemClass.newInstance(); } catch (InstantiationException e) { @@ -92,6 +93,18 @@ public abstract class GameGlobals{ } } + if(automaticActionSummaryOverlay == null){ + try { + automaticActionSummaryOverlay = (AutomaticActionSummaryOverlayBase) ScenarioImplementation.automaticActionSummaryScreen.newInstance(); + } catch (InstantiationException e) { + System.out.println("Error instantiating automatic action performer."); + throw e; + } catch (IllegalAccessException e) { + System.out.println("Error accessing automatic action performer."); + throw e; + } + } + gameWorld.setSystem(new MarkerPositioningSystem()); gameWorld.setSystem(new RobotArmPositioningSystem(), Ouya.runningOnOuya); gameWorld.setSystem(new GeometrySystem()); @@ -106,8 +119,13 @@ public abstract class GameGlobals{ gameWorld.initialize(); } - public static void clearGameSettings(){ - ImmutableBag systems = gameWorld.getSystems(); + public static void dispose() throws IllegalStateException{ + ImmutableBag systems; + + if(entityCreator == null || gameWorld == null || gameLogicSystem == null || automaticActionPerformer == null || automaticActionSummaryOverlay == null) + throw new IllegalStateException("Calling dispose before init or after previous dispose."); + + systems = gameWorld.getSystems(); for(int i = 0; i < systems.size(); i++){ if(systems.get(i) instanceof Disposable){ @@ -115,38 +133,64 @@ public abstract class GameGlobals{ } } + automaticActionSummaryOverlay.dispose(); entityCreator.dispose(); - entityCreator = null; - gameLogicSystem = null; - gameWorld = null; + + entityCreator = null; + gameLogicSystem = null; + gameWorld = null; + automaticActionPerformer = null; + automaticActionSummaryOverlay = null; System.gc(); } /** * @return the entityCreator */ - public static EntityCreatorBase getEntityCreator() { + public static EntityCreatorBase getEntityCreator() throws IllegalStateException{ + if(entityCreator == null) + throw new IllegalStateException("Calling getEntityCreator() before init."); + return entityCreator; } /** * @return the gameLogicSystem */ - public static GameLogicSystemBase getGameLogicSystem() { + public static GameLogicSystemBase getGameLogicSystem() throws IllegalStateException{ + if(gameLogicSystem == null) + throw new IllegalStateException("Calling getGameLogicSystem() before init."); + return gameLogicSystem; } /** * @return the gameWorld */ - public static World getGameWorld() { + public static World getGameWorld() throws IllegalStateException{ + if(gameWorld == null) + throw new IllegalStateException("Calling getGameWorld() before init."); + return gameWorld; } /** * @return the automaticActionPerformer */ - public static AutomaticActionPerformerBase getAutomaticActionPerformer() { + public static AutomaticActionPerformerBase getAutomaticActionPerformer() throws IllegalStateException{ + if(automaticActionPerformer == null) + throw new IllegalStateException("Calling getAutomaticActionPerformer() before init."); + return automaticActionPerformer; } + + /** + * @return the automaticActionSummaryScreen + */ + public static AutomaticActionSummaryOverlayBase getAutomaticActionSummaryOverlay() throws IllegalStateException{ + if(automaticActionSummaryOverlay == null) + throw new IllegalStateException("Calling getAutomaticActionSummaryOverlay() before init."); + + return automaticActionSummaryOverlay; + } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/ScenarioImplementation.java b/src/ve/ucv/ciens/ccg/nxtar/game/ScenarioImplementation.java index 303bd50..1d8c0ac 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/ScenarioImplementation.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/ScenarioImplementation.java @@ -16,6 +16,7 @@ package ve.ucv.ciens.ccg.nxtar.game; import ve.ucv.ciens.ccg.nxtar.game.bombgame.BombGameAutomaticActionPerformer; +import ve.ucv.ciens.ccg.nxtar.game.bombgame.BombGameAutomaticActionSummaryOverlay; import ve.ucv.ciens.ccg.nxtar.game.bombgame.BombGameEntityCreator; import ve.ucv.ciens.ccg.nxtar.game.bombgame.BombGameLogicSystem; @@ -24,6 +25,7 @@ public final class ScenarioImplementation{ public static Class gameLogicSystemClass = BombGameLogicSystem.class; public static Class entityCreatorClass = BombGameEntityCreator.class; public static Class automaticActionPerformerClass = BombGameAutomaticActionPerformer.class; + public static Class automaticActionSummaryScreen = BombGameAutomaticActionSummaryOverlay.class; private ScenarioImplementation(){} } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionPerformer.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionPerformer.java index 3e04729..7aa2128 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionPerformer.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionPerformer.java @@ -18,58 +18,132 @@ package ve.ucv.ciens.ccg.nxtar.game.bombgame; import java.util.LinkedList; import java.util.List; -import com.badlogic.gdx.Gdx; - import ve.ucv.ciens.ccg.nxtar.game.AutomaticActionPerformerBase; +import ve.ucv.ciens.ccg.nxtar.game.GameGlobals; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; +import com.artemis.Entity; +import com.artemis.World; +import com.artemis.managers.GroupManager; +import com.artemis.utils.ImmutableBag; +import com.badlogic.gdx.Gdx; + public class BombGameAutomaticActionPerformer extends AutomaticActionPerformerBase { - private static final int GOAL_FLOOR_MIN_LUMINANCE = 85; - private static final int MARKER_NEARBY_FLOOR_MIN_LUMINANCE = 45; + private static final String TAG = "BOMB_GAME_AUTO_PERFORMER"; + private static final String CLASS_NAME = BombGameAutomaticActionPerformer.class.getSimpleName(); + private static final int GOAL_FLOOR_MIN_LUMINANCE = 75; + private static final int MARKER_NEARBY_FLOOR_MIN_LUMINANCE = 45; private enum action_state_t{ START, WALK_FORWARD, DETECT_MARKER, FINISHING, END; } - private automatic_action_t nextAction; - private action_state_t state; - private List detectedMarkers; - private float then; + public class BombGameAutomaticActionSummary extends AutomaticActionSummary{ + private int numCombinationBombs; + private int numInclinationBombs; + private int numWireBombs; + + public BombGameAutomaticActionSummary(){ + reset(); + } + + public int getNumCombinationBombs() { + return numCombinationBombs; + } + + public int getNumInclinationBombs() { + return numInclinationBombs; + } + + public int getNumWireBombs() { + return numWireBombs; + } + + public void addCombinationBomb(){ + numCombinationBombs++; + } + + public void addInclinationBomb(){ + numInclinationBombs++; + } + + public void addWireBomb(){ + numWireBombs++; + } + + @Override + public void reset() { + this.numCombinationBombs = 0; + this.numInclinationBombs = 0; + this.numWireBombs = 0; + } + } + + private automatic_action_t nextAction; + private action_state_t state; + private List detectedMarkers; + private float then; + private float now; + private GroupManager manager; + private BombGameAutomaticActionSummary summary; public BombGameAutomaticActionPerformer(){ nextAction = automatic_action_t.NO_ACTION; state = action_state_t.START; detectedMarkers = new LinkedList(); then = 0.0f; + now = 0.0f; + manager = null; + summary = new BombGameAutomaticActionSummary(); } @Override public boolean performAutomaticAction(int lightSensorReading, MarkerData markers) throws IllegalStateException, IllegalArgumentException{ - boolean finish = false; - int detectedCode = -1; - float now, deltaT; + BombComponent bomb; + boolean finish = false; + boolean markerDetected = false; + int detectedCode = -1; + ImmutableBag entities = null; + float deltaT; + World world; + + if(manager == null){ + world = GameGlobals.getGameWorld(); + if(world == null) + throw new IllegalStateException("World is null after getGameWorld()."); + + manager = world.getManager(GroupManager.class); + if(manager == null) + throw new IllegalStateException("World has no group managers."); + } if(markers == null) throw new IllegalArgumentException("Markers is null"); switch(state){ case START: + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is START."); + summary.reset(); nextAction = automatic_action_t.ROTATE_90; state = action_state_t.WALK_FORWARD; finish = false; break; case WALK_FORWARD: + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is WALK_FORWARD."); if(lightSensorReading >= GOAL_FLOOR_MIN_LUMINANCE){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Found goal."); nextAction = automatic_action_t.STOP; - state = action_state_t.END; + state = action_state_t.FINISHING; }else{ if(lightSensorReading >= MARKER_NEARBY_FLOOR_MIN_LUMINANCE && lightSensorReading < GOAL_FLOOR_MIN_LUMINANCE){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): There is a marker nearby."); nextAction = automatic_action_t.STOP; state = action_state_t.DETECT_MARKER; then = Gdx.graphics.getDeltaTime(); }else{ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Walking."); nextAction = automatic_action_t.GO_FORWARD; } } @@ -77,35 +151,68 @@ public class BombGameAutomaticActionPerformer extends AutomaticActionPerformerBa break; case DETECT_MARKER: - for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is DETECT_MARKER."); + for(int i = 0; !markerDetected && i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ // Check if this marker has not been detected already. for(Integer code : detectedMarkers){ if(markers.markerCodes[i] == code){ - i = ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Marker already detected."); + markerDetected = true; break; } } // If the marker has not been detected before then examine it. - if(i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS){ + if(!markerDetected){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): New marker detected."); detectedCode = markers.markerCodes[i]; - // TODO: If marker is a bomb then add it to the summary. + entities = manager.getEntities(Integer.toString(detectedCode)); + + for(int e = 0; entities != null && e < entities.size() && entities.get(e) != null; e++){ + bomb = entities.get(e).getComponent(BombComponent.class); + + if(bomb == null){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Entity has no bomb component. Skipping."); + }else{ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Adding bomb."); + switch(bomb.bombType){ + case COMBINATION: + summary.addCombinationBomb(); + break; + case INCLINATION: + summary.addInclinationBomb(); + break; + case WIRES: + summary.addWireBomb(); + break; + default: + throw new IllegalStateException("Unrecognized bomb type."); + } + break; + } + } + + break; } } - if(detectedCode == -1) + if(!markerDetected && detectedCode != -1) detectedMarkers.add(detectedCode); if(lightSensorReading < MARKER_NEARBY_FLOOR_MIN_LUMINANCE){ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Switching to WALK_FORWARD."); state = action_state_t.WALK_FORWARD; nextAction = automatic_action_t.STOP; then = 0.0f; + now = 0.0f; }else{ - now = Gdx.graphics.getDeltaTime(); - deltaT = now - then; + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Clearing MARKER_NEARBY_FLOOR."); + now += Gdx.graphics.getDeltaTime(); + deltaT = now - then; if(deltaT >= 2.0f){ nextAction = automatic_action_t.GO_FORWARD; then = Gdx.graphics.getDeltaTime(); + now = 0.0f; } } @@ -114,16 +221,20 @@ public class BombGameAutomaticActionPerformer extends AutomaticActionPerformerBa break; case FINISHING: - detectedMarkers.clear(); - state = action_state_t.END; + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is FINISHING."); + state = action_state_t.END; nextAction = automatic_action_t.RECENTER; - finish = false; + finish = false; break; case END: - state = action_state_t.START; + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is END."); nextAction = automatic_action_t.NO_ACTION; - finish = true; + state = action_state_t.START; + finish = true; + now = 0.0f; + then = 0.0f; + detectedMarkers.clear(); break; default: @@ -151,4 +262,19 @@ public class BombGameAutomaticActionPerformer extends AutomaticActionPerformerBa return automatic_action_t.RECENTER; } } + + @Override + public AutomaticActionSummary getSummary() { + return (AutomaticActionSummary)summary; + } + + @Override + public void reset() { + Gdx.app.log(TAG, CLASS_NAME + ".reset(): Reset requested."); + detectedMarkers.clear(); + summary.reset(); + state = action_state_t.START; + nextAction = automatic_action_t.NO_ACTION; + then = 0.0f; + } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionSummaryOverlay.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionSummaryOverlay.java new file mode 100644 index 0000000..440e649 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameAutomaticActionSummaryOverlay.java @@ -0,0 +1,127 @@ +/* + * 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.game.bombgame; + +import ve.ucv.ciens.ccg.nxtar.game.AutomaticActionPerformerBase.AutomaticActionSummary; +import ve.ucv.ciens.ccg.nxtar.game.AutomaticActionSummaryOverlayBase; +import ve.ucv.ciens.ccg.nxtar.game.bombgame.BombGameAutomaticActionPerformer.BombGameAutomaticActionSummary; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; +import ve.ucv.ciens.ccg.nxtar.utils.Utils; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; + +public class BombGameAutomaticActionSummaryOverlay extends AutomaticActionSummaryOverlayBase{ + private static final float CANNONICAL_SCREEN_WIDTH = 800.0f; + + private Texture inclinationBombTexture; + private Texture combinationBombTexture; + private Texture wireBombTexture; + private BitmapFont font; + private BitmapFont titleFont; + private Sprite inclinationBomb; + private Sprite combinationBomb; + private Sprite wireBomb; + private float inclinationX; + private float combinationX; + private float wireX; + private float inclinationY; + private float combinationY; + private float wireY; + private float titleWidth; + private float titleHeight; + + public BombGameAutomaticActionSummaryOverlay(){ + FreeTypeFontGenerator fontGenerator; + FreeTypeFontParameter fontParameters; + + inclinationBombTexture = new Texture(Gdx.files.internal("data/gfx/bomb_game/incl_bomb.png")); + combinationBombTexture = new Texture(Gdx.files.internal("data/gfx/bomb_game/comb_bomb.png")); + wireBombTexture = new Texture(Gdx.files.internal("data/gfx/bomb_game/wire_bomb.png")); + + inclinationBomb = new Sprite(inclinationBombTexture); + combinationBomb = new Sprite(combinationBombTexture); + wireBomb = new Sprite(wireBombTexture); + + inclinationBomb.setSize(inclinationBomb.getWidth() * 0.5f, inclinationBomb.getHeight() * 0.5f); + combinationBomb.setSize(combinationBomb.getWidth() * 0.5f, combinationBomb.getHeight() * 0.5f); + wireBomb.setSize(wireBomb.getWidth() * 0.5f, wireBomb.getHeight() * 0.5f); + + combinationBomb.setPosition(-(Utils.getScreenWidthWithOverscan() / 4.0f) - combinationBomb.getWidth(), -(combinationBomb.getHeight() / 2.0f)); + inclinationBomb.setPosition(-(Utils.getScreenWidthWithOverscan() / 4.0f) - inclinationBomb.getWidth(), combinationBomb.getY() + combinationBomb.getHeight() + 10.0f); + wireBomb.setPosition(-(Utils.getScreenWidthWithOverscan() / 4.0f) - wireBomb.getWidth(), combinationBomb.getY() - wireBomb.getHeight() - 10.0f); + + fontParameters = new FreeTypeFontParameter(); + fontParameters.characters = ProjectConstants.FONT_CHARS; + fontParameters.size = (int)((float)ProjectConstants.MENU_BUTTON_FONT_SIZE * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH)); + fontParameters.flip = false; + fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf")); + + font = fontGenerator.generateFont(fontParameters); + font.setColor(Color.YELLOW); + + fontParameters.size = (int)(90.0f * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH)); + titleFont = fontGenerator.generateFont(fontParameters); + + fontGenerator.dispose(); + + inclinationX = inclinationBomb.getX() + inclinationBomb.getWidth() + 15.0f; + combinationX = combinationBomb.getX() + combinationBomb.getWidth() + 15.0f; + wireX = wireBomb.getX() + wireBomb.getWidth() + 15.0f; + + inclinationY = inclinationBomb.getY() + (inclinationBomb.getWidth() / 2.0f) - (font.getCapHeight() / 2.0f); + combinationY = combinationBomb.getY() + (combinationBomb.getWidth() / 2.0f) - (font.getCapHeight() / 2.0f); + wireY = wireBomb.getY() + (wireBomb.getWidth() / 2.0f) - (font.getCapHeight() / 2.0f); + + titleWidth = titleFont.getBounds("Summary").width; + titleHeight = titleFont.getBounds("Summary").height; + } + + @Override + public void dispose() { + inclinationBombTexture.dispose(); + combinationBombTexture.dispose(); + wireBombTexture.dispose(); + font.dispose(); + titleFont.dispose(); + } + + @Override + public void render(SpriteBatch batch, AutomaticActionSummary summary) throws ClassCastException{ + BombGameAutomaticActionSummary bombGameSummary; + + if(!(summary instanceof BombGameAutomaticActionSummary)) + throw new ClassCastException("Summary is not a bomb game summary."); + + bombGameSummary = (BombGameAutomaticActionSummary)summary; + + inclinationBomb.draw(batch); + combinationBomb.draw(batch); + wireBomb.draw(batch); + + font.draw(batch, String.format("Inclination bombs: %d", bombGameSummary.getNumInclinationBombs()), inclinationX, inclinationY); + font.draw(batch, String.format("Combination bombs: %d", bombGameSummary.getNumCombinationBombs()), combinationX, combinationY); + font.draw(batch, String.format("Wire bombs: %d", bombGameSummary.getNumWireBombs()), wireX, wireY); + + titleFont.draw(batch, "Summary", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - titleHeight - 10); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityCreator.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityCreator.java index 8369159..fcfdd2a 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityCreator.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityCreator.java @@ -269,7 +269,6 @@ public class BombGameEntityCreator extends EntityCreatorBase{ private void addBomb(EntityParameters parameters, bomb_type_t type) throws IllegalArgumentException{ Entity bomb; - BombComponent bombComponent = new BombComponent(currentBombId, type); // Create a bomb entity and add it's generic components. bomb = world.createEntity(); @@ -277,54 +276,54 @@ public class BombGameEntityCreator extends EntityCreatorBase{ bomb.addComponent(new EnvironmentComponent(parameters.environment)); bomb.addComponent(new ShaderComponent(parameters.shader)); bomb.addComponent(new MarkerCodeComponent(parameters.markerCode)); - bomb.addComponent(bombComponent); + bomb.addComponent(new BombComponent(currentBombId, type)); bomb.addComponent(new VisibilityComponent()); // Add the collision and render models depending on the bomb type. if(type == bomb_type_t.COMBINATION){ bomb.addComponent(new RenderModelComponent(combinationBombModel)); bomb.addComponent(new CollisionModelComponent(combinationBombCollisionModel)); - addBombCombinationButtons(parameters, bombComponent); + addBombCombinationButtons(parameters); if(DEBUG_RENDER_BOMB_COLLISION_MODELS) addDebugCollisionModelRenderingEntity(combinationBombCollisionModel, parameters, false); }else if(type == bomb_type_t.INCLINATION){ bomb.addComponent(new RenderModelComponent(inclinationBombModel)); bomb.addComponent(new CollisionModelComponent(inclinationBombCollisionModel)); - addBombInclinationButton(parameters, bombComponent); + addBombInclinationButton(parameters); if(DEBUG_RENDER_BOMB_COLLISION_MODELS) addDebugCollisionModelRenderingEntity(inclinationBombCollisionModel, parameters, false); }else if(type == bomb_type_t.WIRES){ bomb.addComponent(new RenderModelComponent(wiresBombModel)); bomb.addComponent(new CollisionModelComponent(wiresBombCollisionModel)); - addBombWires(parameters, bombComponent); + addBombWires(parameters); if(DEBUG_RENDER_BOMB_COLLISION_MODELS) addDebugCollisionModelRenderingEntity(wiresBombCollisionModel, parameters, false); }else throw new IllegalArgumentException("Unrecognized bomb type: " + Integer.toString(type.getValue())); - // Add the bomb and increase the id for the next one. - //groupManager.add(bomb, CollisionDetectionSystem.COLLIDABLE_OBJECT); + // Add the bomb to the world and the respective marker group. Then increase the id for the next bomb. + groupManager.add(bomb, Integer.toString(parameters.markerCode)); bomb.addToWorld(); entities.add(bomb); currentBombId++; NUM_BOMBS++; } - private void addBombCombinationButtons(EntityParameters parameters, BombComponent bomb){ + private void addBombCombinationButtons(EntityParameters parameters){ Entity button1, button2, button3, button4; - button1 = addBombParaphernalia(combinationButton1Model, combinationButton1CollisionModel, bomb, parameters); - button2 = addBombParaphernalia(combinationButton2Model, combinationButton2CollisionModel, bomb, parameters); - button3 = addBombParaphernalia(combinationButton3Model, combinationButton3CollisionModel, bomb, parameters); - button4 = addBombParaphernalia(combinationButton4Model, combinationButton4CollisionModel, bomb, parameters); + button1 = addBombParaphernalia(combinationButton1Model, combinationButton1CollisionModel, parameters); + button2 = addBombParaphernalia(combinationButton2Model, combinationButton2CollisionModel, parameters); + button3 = addBombParaphernalia(combinationButton3Model, combinationButton3CollisionModel, parameters); + button4 = addBombParaphernalia(combinationButton4Model, combinationButton4CollisionModel, parameters); - button1.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.COM_BUTTON_1)); - button2.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.COM_BUTTON_2)); - button3.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.COM_BUTTON_3)); - button4.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.COM_BUTTON_4)); + button1.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.COM_BUTTON_1)); + button2.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.COM_BUTTON_2)); + button3.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.COM_BUTTON_3)); + button4.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.COM_BUTTON_4)); button1.addToWorld(); button2.addToWorld(); @@ -332,31 +331,31 @@ public class BombGameEntityCreator extends EntityCreatorBase{ button4.addToWorld(); } - private void addBombInclinationButton(EntityParameters parameters, BombComponent bomb){ + private void addBombInclinationButton(EntityParameters parameters){ Entity button; - button = addBombParaphernalia(inclinationBombButtonModel, inclinationBombButtonCollisionModel, bomb, parameters); - button.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.BIG_BUTTON)); + button = addBombParaphernalia(inclinationBombButtonModel, inclinationBombButtonCollisionModel, parameters); + button.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.BIG_BUTTON)); button.addToWorld(); } - private void addBombWires(EntityParameters parameters, BombComponent bomb){ + private void addBombWires(EntityParameters parameters){ Entity wire1, wire2, wire3; - wire1 = addBombParaphernalia(wiresBombModelWire1, wiresBombCollisionModelWire1, bomb, parameters); - wire2 = addBombParaphernalia(wiresBombModelWire2, wiresBombCollisionModelWire2, bomb, parameters); - wire3 = addBombParaphernalia(wiresBombModelWire3, wiresBombCollisionModelWire3, bomb, parameters); + wire1 = addBombParaphernalia(wiresBombModelWire1, wiresBombCollisionModelWire1, parameters); + wire2 = addBombParaphernalia(wiresBombModelWire2, wiresBombCollisionModelWire2, parameters); + wire3 = addBombParaphernalia(wiresBombModelWire3, wiresBombCollisionModelWire3, parameters); - wire1.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.BOMB_WIRE_1)); - wire2.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.BOMB_WIRE_2)); - wire3.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.BOMB_WIRE_3)); + wire1.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.BOMB_WIRE_1)); + wire2.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.BOMB_WIRE_2)); + wire3.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.BOMB_WIRE_3)); wire1.addToWorld(); wire2.addToWorld(); wire3.addToWorld(); } - private Entity addBombParaphernalia(Model renderModel, Model collisionModel, BombComponent bomb, EntityParameters parameters){ + private Entity addBombParaphernalia(Model renderModel, Model collisionModel, EntityParameters parameters){ Entity thing; thing = world.createEntity(); @@ -365,7 +364,6 @@ public class BombGameEntityCreator extends EntityCreatorBase{ thing.addComponent(new ShaderComponent(parameters.shader)); thing.addComponent(new RenderModelComponent(renderModel)); thing.addComponent(new CollisionModelComponent(collisionModel)); - thing.addComponent(new BombComponent(bomb)); thing.addComponent(new VisibilityComponent()); thing.addComponent(new MarkerCodeComponent(parameters.markerCode)); thing.addComponent(new CollisionDetectionComponent()); @@ -393,7 +391,7 @@ public class BombGameEntityCreator extends EntityCreatorBase{ frame.addComponent(new ShaderComponent(parameters.shader)); frame.addComponent(new VisibilityComponent()); frame.addComponent(new MarkerCodeComponent(parameters.markerCode)); - frame.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.DOOR_FRAME)); + frame.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.DOOR_FRAME)); groupManager.add(frame, Integer.toString(parameters.markerCode)); frame.addToWorld(); @@ -409,7 +407,7 @@ public class BombGameEntityCreator extends EntityCreatorBase{ doorColInstance = door.getComponent(CollisionModelComponent.class).instance; door.addComponent(new AnimationComponent(doorInstance, parameters.nextAnimation, parameters.loopAnimation, doorColInstance)); door.addComponent(new CollisionDetectionComponent()); - door.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.DOOR)); + door.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.DOOR)); groupManager.add(door, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP); groupManager.add(door, Integer.toString(parameters.markerCode)); groupManager.add(door, DOORS_GROUP); diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameObjectTypeComponent.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityTypeComponent.java similarity index 91% rename from src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameObjectTypeComponent.java rename to src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityTypeComponent.java index 61861ae..b472122 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameObjectTypeComponent.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameEntityTypeComponent.java @@ -17,7 +17,7 @@ package ve.ucv.ciens.ccg.nxtar.game.bombgame; import com.artemis.Component; -public class BombGameObjectTypeComponent extends Component { +public class BombGameEntityTypeComponent extends Component { public static final int BOMB_WIRE_1 = 10; public static final int BOMB_WIRE_2 = 11; public static final int BOMB_WIRE_3 = 12; @@ -32,7 +32,7 @@ public class BombGameObjectTypeComponent extends Component { public int type; - public BombGameObjectTypeComponent(int type){ + public BombGameEntityTypeComponent(int type){ this.type = type; } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameLogicSystem.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameLogicSystem.java index aa82fb2..b3fd37c 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameLogicSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGameLogicSystem.java @@ -53,7 +53,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { } } - @Mapper ComponentMapper typeMapper; + @Mapper ComponentMapper typeMapper; @Mapper ComponentMapper animationMapper; @Mapper ComponentMapper visibilityMapper; @Mapper ComponentMapper markerMapper; @@ -61,20 +61,20 @@ public class BombGameLogicSystem extends GameLogicSystemBase { @Mapper ComponentMapper fadeMapper; private MarkerCodeComponent tempMarker; - private BombGameObjectTypeComponent tempType; + private BombGameEntityTypeComponent tempType; private GroupManager manager; private int then; @SuppressWarnings("unchecked") public BombGameLogicSystem(){ - super(Aspect.getAspectForAll(BombGameObjectTypeComponent.class)); + super(Aspect.getAspectForAll(BombGameEntityTypeComponent.class)); manager = null; then = 0; } @Override protected void process(Entity e){ - BombGameObjectTypeComponent typeComponent; + BombGameEntityTypeComponent typeComponent; if(manager == null) manager = world.getManager(GroupManager.class); @@ -82,28 +82,28 @@ public class BombGameLogicSystem extends GameLogicSystemBase { typeComponent = typeMapper.get(e); switch(typeComponent.type){ - case BombGameObjectTypeComponent.BOMB_WIRE_1: - case BombGameObjectTypeComponent.BOMB_WIRE_2: - case BombGameObjectTypeComponent.BOMB_WIRE_3: + case BombGameEntityTypeComponent.BOMB_WIRE_1: + case BombGameEntityTypeComponent.BOMB_WIRE_2: + case BombGameEntityTypeComponent.BOMB_WIRE_3: processWireBomb(e); break; - case BombGameObjectTypeComponent.BIG_BUTTON: + case BombGameEntityTypeComponent.BIG_BUTTON: processInclinationBomb(e); break; - case BombGameObjectTypeComponent.COM_BUTTON_1: - case BombGameObjectTypeComponent.COM_BUTTON_2: - case BombGameObjectTypeComponent.COM_BUTTON_3: - case BombGameObjectTypeComponent.COM_BUTTON_4: + case BombGameEntityTypeComponent.COM_BUTTON_1: + case BombGameEntityTypeComponent.COM_BUTTON_2: + case BombGameEntityTypeComponent.COM_BUTTON_3: + case BombGameEntityTypeComponent.COM_BUTTON_4: processCombinationBomb(e); break; - case BombGameObjectTypeComponent.DOOR: + case BombGameEntityTypeComponent.DOOR: processDoor(e); break; - case BombGameObjectTypeComponent.FADE_EFFECT: + case BombGameEntityTypeComponent.FADE_EFFECT: processFade(e); break; @@ -120,7 +120,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { private void processWireBomb(Entity b){ CollisionDetectionComponent collision; MarkerCodeComponent marker; - BombGameObjectTypeComponent wireType; + BombGameEntityTypeComponent wireType; // Get this wire's parameters. collision = collisionMapper.getSafe(b); @@ -140,7 +140,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { manager.remove(b, Integer.toString(marker.code)); b.deleteFromWorld(); - if(wireType.type != BombGameObjectTypeComponent.BOMB_WIRE_1){ + if(wireType.type != BombGameEntityTypeComponent.BOMB_WIRE_1){ Gdx.app.log(TAG, CLASS_NAME + ".processWireBomb(): Wire bomb exploded."); createFadeOutEffect(); reducePlayerLivesByOne(); @@ -163,7 +163,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { combination_button_state_t state; CollisionDetectionComponent collision; MarkerCodeComponent marker; - BombGameObjectTypeComponent buttonType; + BombGameEntityTypeComponent buttonType; // Get this wire's parameters. collision = collisionMapper.getSafe(b); @@ -360,10 +360,10 @@ public class BombGameLogicSystem extends GameLogicSystemBase { // Enable collisions with the corresponding door frame entity. Disable collisions with other related entities. if(tempMarker != null) tempMarker.enabled = false; if(tempType != null){ - if(tempType.type != BombGameObjectTypeComponent.DOOR_FRAME && tempType.type != BombGameObjectTypeComponent.DOOR){ + if(tempType.type != BombGameEntityTypeComponent.DOOR_FRAME && tempType.type != BombGameEntityTypeComponent.DOOR){ manager.remove(related.get(i), CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP); manager.remove(related.get(i), Integer.toString(markerCode)); - }else if(tempType.type != BombGameObjectTypeComponent.DOOR_FRAME){ + }else if(tempType.type != BombGameEntityTypeComponent.DOOR_FRAME){ manager.add(related.get(i), CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP); } } @@ -373,7 +373,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { /** *

Checks if a combination bomb is being disabled in the correct sequence.

* - * @param buttonType A number between {@link BombGameObjectTypeComponent.COM_BUTTON_1} and {@link BombGameObjectTypeComponent.COM_BUTTON_4}. + * @param buttonType A number between {@link BombGameEntityTypeComponent.COM_BUTTON_1} and {@link BombGameEntityTypeComponent.COM_BUTTON_4}. * @param markerCode A marker code between [0, 1023], inclusive. * @return The current state of the bomb. * @throws IllegalArgumentException If marker code is not in range or if buttonType is not valid. @@ -384,7 +384,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { int remainingButtons = 0; ImmutableBag related; - if(buttonType < BombGameObjectTypeComponent.COM_BUTTON_1 || buttonType > BombGameObjectTypeComponent.COM_BUTTON_4) + if(buttonType < BombGameEntityTypeComponent.COM_BUTTON_1 || buttonType > BombGameEntityTypeComponent.COM_BUTTON_4) throw new IllegalArgumentException("Button is not a valid combination bomb button: " + Integer.toString(buttonType)); if(markerCode < 0 || markerCode > 1023) @@ -398,7 +398,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { if(tempType == null) continue; - if(tempType.type >= BombGameObjectTypeComponent.COM_BUTTON_1 && tempType.type <= BombGameObjectTypeComponent.COM_BUTTON_4){ + if(tempType.type >= BombGameEntityTypeComponent.COM_BUTTON_1 && tempType.type <= BombGameEntityTypeComponent.COM_BUTTON_4){ if(tempType.type >= buttonType){ // If this remaining button is a correct one then skip it. remainingButtons++; @@ -427,7 +427,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { */ private void createFadeOutEffect(){ Entity effect = world.createEntity(); - effect.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.FADE_EFFECT)); + effect.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.FADE_EFFECT)); effect.addComponent(new FadeEffectComponent()); effect.addToWorld(); } @@ -437,7 +437,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase { */ private void createFadeInEffect(){ Entity effect = world.createEntity(); - effect.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.FADE_EFFECT)); + effect.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.FADE_EFFECT)); effect.addComponent(new FadeEffectComponent(true)); effect.addToWorld(); } diff --git a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGamePlayerSystem.java b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGamePlayerSystem.java index d45a7d5..b08a563 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGamePlayerSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/game/bombgame/BombGamePlayerSystem.java @@ -29,7 +29,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.utils.Disposable; public class BombGamePlayerSystem extends PlayerSystemBase implements Disposable{ - private static final float HEART_Y_POS = (Utils.getScreenHeight() / 2) - 69; + private static final float HEART_Y_POS = (Utils.getScreenHeightWithOverscan() / 2) - 69; @Mapper ComponentMapper playerMapper; private SpriteBatch batch; @@ -50,7 +50,7 @@ public class BombGamePlayerSystem extends PlayerSystemBase implements Disposable BombGamePlayerComponent player = playerMapper.get(e); // Render remaining lives. - heartXPos = -(Utils.getScreenWidth() / 2) + 5; + heartXPos = -(Utils.getScreenWidthWithOverscan() / 2) + 5; for(int i = 0; i < player.lives; ++i){ heart.setPosition(heartXPos, HEART_Y_POS); heart.draw(batch); diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java index 3ad1abb..cdfea66 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java @@ -85,6 +85,7 @@ public class AutomaticActionState extends BaseState{ private boolean ignoreBackKey; private boolean automaticActionEnabled; private AutomaticActionPerformerBase automaticActionPerformer; + private automatic_action_t previousAction; // Cameras. private OrthographicCamera unitaryOrthographicCamera; @@ -136,6 +137,7 @@ public class AutomaticActionState extends BaseState{ automaticActionEnabled = false; startButtonPressed = false; automaticActionPerformer = GameGlobals.getAutomaticActionPerformer(); + previousAction = automatic_action_t.NO_ACTION; // Set up the cameras. pixelPerfectOrthographicCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); @@ -306,11 +308,11 @@ public class AutomaticActionState extends BaseState{ 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.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan()); renderableVideoFrame.rotate90(true); renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2); - frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); + frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan()); frameBufferSprite.rotate90(true); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2); } @@ -342,6 +344,14 @@ public class AutomaticActionState extends BaseState{ data = null; } + @Override + public void pause(){ + automaticActionPerformer.reset(); + startButton.setDisabled(false); + ignoreBackKey = false; + automaticActionEnabled = false; + } + @Override public void dispose(){ SensorReportThread.freeInstance(); @@ -457,104 +467,109 @@ public class AutomaticActionState extends BaseState{ if(!automaticActionPerformer.performAutomaticAction(sensorThread.getLightSensorReading(), data)){ nextAction = automaticActionPerformer.getNextAction(); - switch(nextAction){ - case GO_BACKWARDS: - event1 = new MotorEvent(); - event2 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_A); - event1.setPower((byte)-100); - event2.setMotor(motor_t.MOTOR_C); - event2.setPower((byte)-100); - break; + if(nextAction != previousAction){ + switch(nextAction){ + case GO_BACKWARDS: + event1 = new MotorEvent(); + event2 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_A); + event1.setPower((byte)-20); + event2.setMotor(motor_t.MOTOR_C); + event2.setPower((byte)-20); + break; - case GO_FORWARD: - event1 = new MotorEvent(); - event2 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_A); - event1.setPower((byte)100); - event2.setMotor(motor_t.MOTOR_C); - event2.setPower((byte)100); - break; + case GO_FORWARD: + event1 = new MotorEvent(); + event2 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_A); + event1.setPower((byte)20); + event2.setMotor(motor_t.MOTOR_C); + event2.setPower((byte)20); + break; - case STOP: - event1 = new MotorEvent(); - event2 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_A); - event1.setPower((byte)0); - event2.setMotor(motor_t.MOTOR_C); - event2.setPower((byte)0); - break; + case STOP: + event1 = new MotorEvent(); + event2 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_A); + event1.setPower((byte)0); + event2.setMotor(motor_t.MOTOR_C); + event2.setPower((byte)0); + break; - case ROTATE_90: - event1 = new MotorEvent(); - event1.setMotor(motor_t.ROTATE_90); - event1.setPower((byte)100); - break; + case ROTATE_90: + event1 = new MotorEvent(); + event1.setMotor(motor_t.ROTATE_90); + event1.setPower((byte)20); + break; - case RECENTER: - event1 = new MotorEvent(); - event1.setMotor(motor_t.RECENTER); - event1.setPower((byte)100); - break; + case RECENTER: + event1 = new MotorEvent(); + event1.setMotor(motor_t.RECENTER); + event1.setPower((byte)20); + break; - case TURN_LEFT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_A); - event1.setPower((byte)100); - break; + case TURN_LEFT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_A); + event1.setPower((byte)20); + break; - case TURN_RIGHT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_C); - event1.setPower((byte)100); - break; + case TURN_RIGHT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_C); + event1.setPower((byte)20); + break; - case BACKWARDS_LEFT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_C); - event1.setPower((byte)-100); - break; + case BACKWARDS_LEFT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_C); + event1.setPower((byte)-20); + break; - case BACKWARDS_RIGHT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_A); - event1.setPower((byte)-100); - break; + case BACKWARDS_RIGHT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_A); + event1.setPower((byte)-20); + break; - case LOOK_RIGHT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_B); - event1.setPower((byte)25); - break; + case LOOK_RIGHT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_B); + event1.setPower((byte)25); + break; - case LOOK_LEFT: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_B); - event1.setPower((byte)-25); - break; + case LOOK_LEFT: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_B); + event1.setPower((byte)-25); + break; - case STOP_LOOKING: - event1 = new MotorEvent(); - event1.setMotor(motor_t.MOTOR_B); - event1.setPower((byte)0); - break; + case STOP_LOOKING: + event1 = new MotorEvent(); + event1.setMotor(motor_t.MOTOR_B); + event1.setPower((byte)0); + break; - case NO_ACTION: - default: - break; + case NO_ACTION: + default: + break; + } + + if(event1 != null) + queue.addEvent(event1); + if(event2 != null) + queue.addEvent(event2); + + previousAction = nextAction; + }else{ + Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Skipping repeated action."); } - if(event1 != null) - queue.addEvent(event1); - if(event2 != null) - queue.addEvent(event2); - }else{ - // TODO: Go to summary screen. startButton.setDisabled(false); ignoreBackKey = false; automaticActionEnabled = false; - core.nextState = game_states_t.MAIN_MENU; + core.nextState = game_states_t.SUMMARY; } }catch(IllegalArgumentException e){ diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionSummaryState.java b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionSummaryState.java new file mode 100644 index 0000000..f5285b3 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionSummaryState.java @@ -0,0 +1,330 @@ +/* + * 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.game.AutomaticActionPerformerBase; +import ve.ucv.ciens.ccg.nxtar.game.AutomaticActionSummaryOverlayBase; +import ve.ucv.ciens.ccg.nxtar.game.GameGlobals; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; +import ve.ucv.ciens.ccg.nxtar.utils.Utils; + +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.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +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.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; + +public class AutomaticActionSummaryState extends BaseState{ + private static final String TAG = "AUTO_SUMMARY"; + private static final String CLASS_NAME = AutomaticActionSummaryState.class.getSimpleName(); + private static final String SHADER_PATH = "shaders/movingBckg/movingBckg"; + + // Helper fields. + private float u_scaling[]; + private float u_displacement; + + // Buttons and other gui components. + private TextButton continueButton; + private Rectangle continueButtonBBox; + private Sprite background; + private Texture backgroundTexture; + private ShaderProgram backgroundShader; + private Texture ouyaOButtonTexture; + private Sprite ouyaOButton; + private boolean oButtonPressed; + + // Graphic data for the start button. + private Texture buttonEnabledTexture; + private Texture buttonDisabledTexture; + private Texture buttonPressedTexture; + private NinePatch buttonEnabled9p; + private NinePatch buttonDisabled9p; + private NinePatch buttonPressed9p; + private BitmapFont font; + + // Summary overlay related fields. + AutomaticActionPerformerBase automaticActionPerformer; + AutomaticActionSummaryOverlayBase summaryOverlay; + + // Button touch helper fields. + private boolean continueButtonTouched; + private int continueButtonTouchPointer; + + public AutomaticActionSummaryState(NxtARCore core) throws IllegalArgumentException{ + TextButtonStyle textButtonStyle; + FreeTypeFontGenerator fontGenerator; + FreeTypeFontParameter fontParameters; + + if(core == null) + throw new IllegalArgumentException(CLASS_NAME + ": Core is null."); + + this.core = core; + this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + oButtonPressed = false; + automaticActionPerformer = GameGlobals.getAutomaticActionPerformer(); + summaryOverlay = GameGlobals.getAutomaticActionSummaryOverlay(); + + // Create the start button background. + buttonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png")); + buttonEnabled9p = new NinePatch(new TextureRegion(buttonEnabledTexture, 0, 0, buttonEnabledTexture.getWidth(), buttonEnabledTexture.getHeight()), 49, 49, 45, 45); + buttonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png")); + buttonDisabled9p = new NinePatch(new TextureRegion(buttonDisabledTexture, 0, 0, buttonDisabledTexture.getWidth(), buttonDisabledTexture.getHeight()), 49, 49, 45, 45); + buttonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png")); + buttonPressed9p = new NinePatch(new TextureRegion(buttonPressedTexture, 0, 0, buttonPressedTexture.getWidth(), buttonPressedTexture.getHeight()), 49, 49, 45, 45); + + // Create the start button font. + fontParameters = new FreeTypeFontParameter(); + fontParameters.characters = ProjectConstants.FONT_CHARS; + fontParameters.size = ProjectConstants.MENU_BUTTON_FONT_SIZE; + fontParameters.flip = false; + fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf")); + font = fontGenerator.generateFont(fontParameters); + fontGenerator.dispose(); + + // Create the contine button. + textButtonStyle = new TextButtonStyle(); + textButtonStyle.font = font; + textButtonStyle.up = new NinePatchDrawable(buttonEnabled9p); + textButtonStyle.checked = new NinePatchDrawable(buttonPressed9p); + textButtonStyle.disabled = new NinePatchDrawable(buttonDisabled9p); + textButtonStyle.fontColor = new Color(Color.BLACK); + textButtonStyle.downFontColor = new Color(Color.WHITE); + textButtonStyle.disabledFontColor = new Color(Color.BLACK); + + continueButton = new TextButton("Continue", textButtonStyle); + continueButton.setText("Continue"); + continueButton.setPosition(-(continueButton.getWidth() / 2), -(Utils.getScreenHeightWithOverscan() / 2) + 10); + continueButtonBBox = new Rectangle(0, 0, continueButton.getWidth(), continueButton.getHeight()); + continueButtonBBox.setPosition(continueButton.getX(), continueButton.getY()); + + // Set OUYA's O button. + if(Ouya.runningOnOuya){ + ouyaOButtonTexture = new Texture("data/gfx/gui/OUYA_O.png"); + ouyaOButton = new Sprite(ouyaOButtonTexture); + ouyaOButton.setSize(ouyaOButton.getWidth() * 0.6f, ouyaOButton.getHeight() * 0.6f); + oButtonPressed = false; + }else{ + ouyaOButtonTexture = null; + } + + // 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)); + + backgroundShader = new ShaderProgram(Gdx.files.internal(SHADER_PATH + "_vert.glsl"), Gdx.files.internal(SHADER_PATH + "_frag.glsl")); + if(!backgroundShader.isCompiled()){ + Gdx.app.error(TAG, CLASS_NAME + ".MainMenuStateBase() :: Failed to compile the background shader."); + Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog()); + backgroundShader = null; + } + + u_scaling = new float[2]; + u_scaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; + u_scaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; + + u_displacement = 1.0f; + + win2world = new Vector3(0.0f, 0.0f, 0.0f); + touchPointWorldCoords = new Vector2(); + continueButtonTouched = false; + continueButtonTouchPointer = -1; + stateActive = false; + } + + @Override + public void render(float delta){ + Gdx.gl.glClearColor(1, 1, 1, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + core.batch.setProjectionMatrix(pixelPerfectCamera.combined); + core.batch.begin();{ + + // Render background. + core.batch.disableBlending(); + drawBackground(core.batch); + core.batch.enableBlending(); + + summaryOverlay.render(core.batch, automaticActionPerformer.getSummary()); + + // Render buttons. + continueButton.draw(core.batch, 1.0f); + if(Ouya.runningOnOuya) + ouyaOButton.draw(core.batch); + + }core.batch.end(); + } + + @Override + public void dispose(){ + buttonEnabledTexture.dispose(); + buttonDisabledTexture.dispose(); + buttonPressedTexture.dispose(); + if(ouyaOButtonTexture != null) + ouyaOButtonTexture.dispose(); + backgroundTexture.dispose(); + if(backgroundShader != null) backgroundShader.dispose(); + font.dispose(); + } + + private void drawBackground(SpriteBatch batch){ + if(backgroundShader != null){ + batch.setShader(backgroundShader); + backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2); + backgroundShader.setUniformf("u_displacement", u_displacement); + } + background.draw(batch); + if(backgroundShader != null) batch.setShader(null); + u_displacement = u_displacement < 0.0f ? 1.0f : u_displacement - 0.0005f; + } + + @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 LISTENER METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;*/ + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button){ + unprojectTouch(screenX, screenY); + + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown(%d, %d, %d, %d)", screenX, screenY, pointer, button)); + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); + + if(!continueButton.isDisabled() && continueButtonBBox.contains(touchPointWorldCoords)){ + continueButton.setChecked(true); + continueButtonTouched = true; + continueButtonTouchPointer = pointer; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed."); + } + + return true; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button){ + unprojectTouch(screenX, screenY); + + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp(%d, %d, %d, %d)", screenX, screenY, pointer, button)); + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); + + if(!continueButton.isDisabled() && continueButtonBBox.contains(touchPointWorldCoords) && continueButtonTouched){ + continueButton.setChecked(false); + continueButtonTouched = false; + continueButtonTouchPointer = -1; + core.nextState = game_states_t.MAIN_MENU; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released."); + } + + return true; + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer){ + unprojectTouch(screenX, screenY); + + if(!continueButton.isDisabled() && continueButtonTouched && pointer == continueButtonTouchPointer && !continueButtonBBox.contains(touchPointWorldCoords)){ + continueButtonTouchPointer = -1; + continueButtonTouched = false; + continueButton.setChecked(false); + Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released."); + } + + return true; + } + + @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){ + if(buttonCode == Ouya.BUTTON_O && !continueButton.isDisabled()){ + Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): O button pressed."); + oButtonPressed = true; + continueButton.setChecked(true); + } + return true; + }else{ + return false; + } + } + + @Override + public boolean buttonUp(Controller controller, int buttonCode){ + if(stateActive){ + if(buttonCode == Ouya.BUTTON_O){ + Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): O button released."); + if(oButtonPressed){ + oButtonPressed = false; + continueButton.setChecked(false); + core.nextState = game_states_t.MAIN_MENU; + } + } + 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 e02542e..e131b06 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -246,8 +246,8 @@ 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; + final float MIN_SLIDER_X = correctAngleLedOnSprite != null ? -(Utils.getScreenWidthWithOverscan() / 2) + 5 + correctAngleLedOnSprite.getWidth() : -(Utils.getScreenWidthWithOverscan() / 2) + 5; + final float MAX_SLIDER_X = correctAngleLedOnSprite != null ? (Utils.getScreenWidthWithOverscan() / 2) - 5 - correctAngleLedOnSprite.getWidth(): (Utils.getScreenWidthWithOverscan() / 2) - 5; int w, h; float t, xSliderPos; byte[] frame; @@ -362,11 +362,11 @@ public class InGameState extends BaseState{ }else{ float xSize = Gdx.graphics.getHeight() * (w / h); - renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); + renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan()); renderableVideoFrame.rotate90(true); renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2); - frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); + frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan()); frameBufferSprite.rotate90(true); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2); } @@ -595,7 +595,7 @@ public class InGameState extends BaseState{ 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); + orientationSlider.setPosition(-(orientationSlider.getWidth() / 2), (Utils.getScreenHeightWithOverscan() / 2) - orientationSlider.getHeight() - 5); } /*;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java b/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java index 7e65221..2b03546 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java @@ -65,8 +65,7 @@ public abstract class MainMenuStateBase extends BaseState{ protected Sprite cameraCalibratedLedOff; protected Sprite assetsLoadedLedOn; protected Sprite assetsLoadedLedOff; - - protected Sprite background; + protected Sprite background; // Graphic data for the start button. private Texture menuButtonEnabledTexture; @@ -102,10 +101,8 @@ public abstract class MainMenuStateBase extends BaseState{ // Create the start button background. menuButtonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png")); menuButtonEnabled9p = new NinePatch(new TextureRegion(menuButtonEnabledTexture, 0, 0, menuButtonEnabledTexture.getWidth(), menuButtonEnabledTexture.getHeight()), 49, 49, 45, 45); - menuButtonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png")); menuButtonDisabled9p = new NinePatch(new TextureRegion(menuButtonDisabledTexture, 0, 0, menuButtonDisabledTexture.getWidth(), menuButtonDisabledTexture.getHeight()), 49, 49, 45, 45); - menuButtonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png")); menuButtonPressed9p = new NinePatch(new TextureRegion(menuButtonPressedTexture, 0, 0, menuButtonPressedTexture.getWidth(), menuButtonPressedTexture.getHeight()), 49, 49, 45, 45); @@ -118,7 +115,7 @@ public abstract class MainMenuStateBase extends BaseState{ font = fontGenerator.generateFont(fontParameters); fontGenerator.dispose(); - // Create the start button. + // Create the buttons. textButtonStyle = new TextButtonStyle(); textButtonStyle.font = font; textButtonStyle.up = new NinePatchDrawable(menuButtonEnabled9p); @@ -133,7 +130,6 @@ public abstract class MainMenuStateBase extends BaseState{ startButton.setDisabled(true); startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight()); - // Create the calibration button. calibrationButton = new TextButton("Calibrate camera", textButtonStyle); calibrationButton.setText("Calibrate camera"); calibrationButton.setDisabled(true); @@ -150,13 +146,10 @@ public abstract class MainMenuStateBase extends BaseState{ region = new TextureRegion(ledOnTexture); cameraCalibratedLedOn = new Sprite(region); - region = new TextureRegion(ledOffTexture); cameraCalibratedLedOff = new Sprite(region); - region = new TextureRegion(ledOnTexture); assetsLoadedLedOn = new Sprite(region); - region = new TextureRegion(ledOffTexture); assetsLoadedLedOff = new Sprite(region); diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java b/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java index 5809214..4390d7a 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java @@ -36,9 +36,12 @@ public class OuyaMainMenuState extends MainMenuStateBase{ private int oButtonSelection; private float ledYPos; - public OuyaMainMenuState(final NxtARCore core){ + public OuyaMainMenuState(final NxtARCore core) throws IllegalArgumentException{ super(); + if(core == null) + throw new IllegalArgumentException(CLASS_NAME + ": Core is null."); + this.core = core; // Set buttons. @@ -50,7 +53,7 @@ public class OuyaMainMenuState extends MainMenuStateBase{ autoButtonBBox.setPosition(autoButton.getX(), autoButton.getY()); //Set leds. - ledYPos = -(Utils.getScreenHeight() / 2) + 10; + ledYPos = -(Utils.getScreenHeightWithOverscan() / 2) + 10; cameraCalibratedLedOn.setSize(cameraCalibratedLedOn.getWidth() * 0.5f, cameraCalibratedLedOn.getHeight() * 0.5f); cameraCalibratedLedOn.setPosition(-cameraCalibratedLedOn.getWidth() - 5, ledYPos); cameraCalibratedLedOff.setSize(cameraCalibratedLedOff.getWidth() * 0.5f, cameraCalibratedLedOff.getHeight() * 0.5f); @@ -111,9 +114,9 @@ public class OuyaMainMenuState extends MainMenuStateBase{ ouyaOButtonTexture.dispose(); } - /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; BEGIN CONTROLLER LISTENER METHODS ; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/ + /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; CONTROLLER LISTENER METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/ @Override public boolean buttonDown(Controller controller, int buttonCode){ diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java b/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java index 8fb8331..763a1c1 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java @@ -22,11 +22,16 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; public class TabletMainMenuState extends MainMenuStateBase{ + private static final String CLASS_NAME = TabletMainMenuState.class.getSimpleName(); + private float ledYPos; - public TabletMainMenuState(final NxtARCore core){ + public TabletMainMenuState(final NxtARCore core) throws IllegalArgumentException{ super(); + if(core == null) + throw new IllegalArgumentException(CLASS_NAME + ": Core is null."); + this.core = core; // Set buttons. @@ -38,7 +43,7 @@ public class TabletMainMenuState extends MainMenuStateBase{ autoButtonBBox.setPosition(autoButton.getX(), autoButton.getY()); // Set leds. - ledYPos = -(Utils.getScreenHeight() / 2) + 10; + ledYPos = -(Utils.getScreenHeightWithOverscan() / 2) + 10; cameraCalibratedLedOn.setSize(cameraCalibratedLedOn.getWidth() * 0.5f, cameraCalibratedLedOn.getHeight() * 0.5f); cameraCalibratedLedOn.setPosition(-cameraCalibratedLedOn.getWidth() - 5, ledYPos); cameraCalibratedLedOff.setSize(cameraCalibratedLedOff.getWidth() * 0.5f, cameraCalibratedLedOff.getHeight() * 0.5f); diff --git a/src/ve/ucv/ciens/ccg/nxtar/utils/ProjectConstants.java b/src/ve/ucv/ciens/ccg/nxtar/utils/ProjectConstants.java index dc13c2c..beda501 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/utils/ProjectConstants.java +++ b/src/ve/ucv/ciens/ccg/nxtar/utils/ProjectConstants.java @@ -35,7 +35,7 @@ public abstract class ProjectConstants{ public static final float OVERSCAN; public static final int MENU_BUTTON_FONT_SIZE; - public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890:"; public static final int MAXIMUM_NUMBER_OF_MARKERS = 5; public static final int CALIBRATION_PATTERN_POINTS = 54; diff --git a/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java b/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java index 137fd52..677ab82 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java +++ b/src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java @@ -41,14 +41,14 @@ public abstract class Utils{ /** * @return The width of the screen accounting for screen overscan. */ - public static int getScreenWidth(){ + public static int getScreenWidthWithOverscan(){ return (int)(Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN); } /** * @return The height of the screen accounting for screen overscan. */ - public static int getScreenHeight(){ + public static int getScreenHeightWithOverscan(){ return (int)(Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN); }