Added instructions screen support.

This commit is contained in:
2014-06-26 12:51:01 -04:30
parent 5a8391aa28
commit 81d8a81b7e
12 changed files with 586 additions and 35 deletions

View File

@@ -28,6 +28,7 @@ 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;
import ve.ucv.ciens.ccg.nxtar.states.InstructionsState;
import ve.ucv.ciens.ccg.nxtar.states.MainMenuStateBase;
import ve.ucv.ciens.ccg.nxtar.states.OuyaMainMenuState;
import ve.ucv.ciens.ccg.nxtar.states.ScenarioEndSummaryState;
@@ -77,7 +78,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), AUTOMATIC_ACTION_SUMMARY(4), SCENARIO_END_SUMMARY(5);
MAIN_MENU(0), IN_GAME(1), CALIBRATION(2), AUTOMATIC_ACTION(3), AUTOMATIC_ACTION_SUMMARY(4), SCENARIO_END_SUMMARY(5), HINTS(6);
private int value;
@@ -90,7 +91,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
}
public static int getNumStates(){
return 6;
return 7;
}
};
@@ -285,6 +286,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
states[game_states_t.AUTOMATIC_ACTION_SUMMARY.getValue()] = new AutomaticActionSummaryState(this);
states[game_states_t.SCENARIO_END_SUMMARY.getValue()] = new ScenarioEndSummaryState(this);
states[game_states_t.HINTS.getValue()] = new InstructionsState(this);
}catch(IllegalArgumentException e){
Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal argument caught creating states: ", e);
@@ -426,6 +428,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
}
// Render the debug overlay.
if(ProjectConstants.DEBUG){
batch.setProjectionMatrix(pixelPerfectCamera.combined);
batch.begin();{
// Draw the FPS overlay.
@@ -438,6 +441,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
font.draw(batch, String.format("Device azimuth: %f", Gdx.input.getAzimuth()), overlayX, overlayY - (6 * font.getCapHeight()) - 30);
}batch.end();
}
}
/**
* <p>Pauses the video streaming and the current state.</p>

View File

@@ -0,0 +1,31 @@
/*
* 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.scenarios;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.Disposable;
/**
* <p>Base class for hint screens.</p>
*/
public abstract class HintsOverlayBase implements Disposable{
/**
* <p>Renders the overlay.</p>
*
* @param batch The {@link SpriteBatch} to use for rendering.
*/
public abstract void render(SpriteBatch batch);
}

View File

@@ -45,6 +45,7 @@ public abstract class ScenarioGlobals{
private static SummaryOverlayBase automaticActionSummaryOverlay = null;
private static PlayerSystemBase playerSystem = null;
private static SummaryOverlayBase scenarioSummaryOverlay = null;
private static HintsOverlayBase hintsOverlay = null;
public static void init(NxtARCore core) throws IllegalArgumentException, InstantiationException, IllegalAccessException{
if(core == null)
@@ -132,6 +133,18 @@ public abstract class ScenarioGlobals{
}
}
if(hintsOverlay == null){
try {
hintsOverlay = (HintsOverlayBase) ScenarioImplementation.hintsOverlayClass.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating hints overlay.");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing hints overlay.");
throw e;
}
}
playerSystem.setCore(core);
gameWorld.setSystem(new MarkerPositioningSystem());
@@ -165,6 +178,7 @@ public abstract class ScenarioGlobals{
scenarioSummaryOverlay.dispose();
automaticActionSummaryOverlay.dispose();
entityCreator.dispose();
hintsOverlay.dispose();
entityCreator = null;
gameLogicSystem = null;
@@ -173,6 +187,7 @@ public abstract class ScenarioGlobals{
automaticActionSummaryOverlay = null;
playerSystem = null;
scenarioSummaryOverlay = null;
hintsOverlay = null;
System.gc();
}
@@ -225,4 +240,11 @@ public abstract class ScenarioGlobals{
return scenarioSummaryOverlay;
}
public static HintsOverlayBase getHintsOverlay() throws IllegalStateException{
if(hintsOverlay == null)
throw new IllegalStateException("Calling getHintsOverlay() before init.");
return hintsOverlay;
}
}

View File

@@ -18,6 +18,7 @@ package ve.ucv.ciens.ccg.nxtar.scenarios;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameAutomaticActionPerformer;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameAutomaticActionSummaryOverlay;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameEntityCreator;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameInstructionsOverlay;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameLogicSystem;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGamePlayerSystem;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGameScenarioEndingOverlay;
@@ -30,6 +31,7 @@ public final class ScenarioImplementation{
public static final Class automaticActionSummaryOverlay = BombGameAutomaticActionSummaryOverlay.class;
public static final Class playerSystemClass = BombGamePlayerSystem.class;
public static final Class scenarioSummaryOverlayClass = BombGameScenarioEndingOverlay.class;
public static final Class hintsOverlayClass = BombGameInstructionsOverlay.class;
private ScenarioImplementation(){}
}

View File

@@ -0,0 +1,120 @@
/*
* 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.scenarios.bombgame;
import ve.ucv.ciens.ccg.nxtar.scenarios.HintsOverlayBase;
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 BombGameInstructionsOverlay extends HintsOverlayBase {
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 BombGameInstructionsOverlay(){
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("Instructions").width;
titleHeight = titleFont.getBounds("Instructions").height;
}
@Override
public void dispose() {
inclinationBombTexture.dispose();
combinationBombTexture.dispose();
wireBombTexture.dispose();
font.dispose();
titleFont.dispose();
}
@Override
public void render(SpriteBatch batch){
String inclText = Utils.deviceHasOrientationSensors() ? "Balance your device" : "Always defuses.";
inclinationBomb.draw(batch);
combinationBomb.draw(batch);
wireBomb.draw(batch);
font.draw(batch, inclText, inclinationX, inclinationY);
font.draw(batch, "Blue, red, gray and green", combinationX, combinationY);
font.draw(batch, "Cut the blue wire.", wireX, wireY);
titleFont.draw(batch, "Instructions", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - titleHeight - 10);
}
}

View File

@@ -227,11 +227,13 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
manager.remove(b, Integer.toString(marker.code));
b.deleteFromWorld();
if(Utils.deviceHasOrientationSensors()){
if(!Utils.isDeviceRollValid() || (Utils.isDeviceRollValid() && Math.abs(Gdx.input.getRoll()) > ProjectConstants.MAX_ABS_ROLL)){
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Inclination bomb exploded.");
createFadeOutEffect();
reducePlayerLivesByOne();
}
}
// Disable all related entities.
disableBomb(marker.code);

View File

@@ -124,6 +124,7 @@ public class InGameState extends BaseState{
private Texture correctAngleLedOnTexture;
private Texture correctAngleLedOffTexture;
private Texture orientationSliderTexture;
private Texture hintButtonTexture;
// Gui renderable sprites.
private Sprite motorAButton;
@@ -142,6 +143,7 @@ public class InGameState extends BaseState{
private Sprite correctAngleLedOnSprite;
private Sprite correctAngleLedOffSprite;
private Sprite orientationSlider;
private Sprite hintButton;
// Button touch helper fields.
private boolean[] buttonsTouched;
@@ -231,6 +233,16 @@ public class InGameState extends BaseState{
if(!Ouya.runningOnOuya)
setUpButtons();
// Set up the hint button.
// Set up the correct angle leds.
hintButtonTexture = new Texture(Gdx.files.internal("data/gfx/gui/help.png"));
hintButton = new Sprite(hintButtonTexture);
hintButton.setSize(hintButton.getWidth() * (Ouya.runningOnOuya ? 0.5f : 0.25f), hintButton.getHeight() * (Ouya.runningOnOuya ? 0.5f : 0.25f));
if(!Ouya.runningOnOuya)
hintButton.setPosition(-(Gdx.graphics.getWidth() / 2) + 5, (Gdx.graphics.getHeight() / 2) - hintButton.getHeight() - 5);
else
hintButton.setPosition(-(Utils.getScreenWidthWithOverscan() / 2) + 5, -hintButton.getHeight() / 2);
// Set up the game world.
gameWorld = ScenarioGlobals.getGameWorld();
@@ -443,6 +455,11 @@ public class InGameState extends BaseState{
}core.batch.end();
}
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
core.batch.begin();{
hintButton.draw(core.batch);
}core.batch.end();
fadeEffectRenderingSystem.process();
playerSystem.process();
@@ -484,6 +501,9 @@ public class InGameState extends BaseState{
if(orientationSliderTexture != null)
orientationSliderTexture.dispose();
if(hintButtonTexture != null)
hintButtonTexture.dispose();
if(backgroundShader != null)
backgroundShader.dispose();
@@ -744,8 +764,10 @@ public class InGameState extends BaseState{
buttonPointers[7] = pointer;
controlMode = controlMode.getValue() == robot_control_mode_t.WHEEL_CONTROL.getValue() ? robot_control_mode_t.ARM_CONTROL : robot_control_mode_t.WHEEL_CONTROL;
}else if(hintButton.getBoundingRectangle().contains(touchPointWorldCoords)){
core.nextState = game_states_t.HINTS;
}else{
if(controlMode == robot_control_mode_t.ARM_CONTROL){
touchPointWorldCoords.set(win2world.x, win2world.y);
if(frameBufferSprite != null && frameBufferSprite.getBoundingRectangle().contains(touchPointWorldCoords)){
@@ -757,6 +779,7 @@ public class InGameState extends BaseState{
Gdx.app.log(TAG, CLASS_NAME + "touchDown(): Touch point outside framebuffer.");
}
}
}
return true;
}
@@ -1060,6 +1083,9 @@ public class InGameState extends BaseState{
if(keycode == Input.Keys.BACK){
core.nextState = game_states_t.MAIN_MENU;
return true;
}else if(keycode == Input.Keys.F1){
core.nextState = game_states_t.HINTS;
return true;
}
switch(keycode){
@@ -1223,7 +1249,9 @@ public class InGameState extends BaseState{
robotArmPositioningSystem.setUserInput(userInput);
robotArmPositioningSystem.process();
}else if(buttonCode == Ouya.BUTTON_A){
}else if(buttonCode == Ouya.BUTTON_U){
core.nextState = game_states_t.HINTS;
}else if(buttonCode == Ouya.BUTTON_A || buttonCode == Ouya.BUTTON_MENU){
core.nextState = game_states_t.MAIN_MENU;
}

View File

@@ -0,0 +1,326 @@
/*
* Copyright (C) 2013 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.scenarios.HintsOverlayBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.ScenarioGlobals;
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 InstructionsState extends BaseState {
private static final String TAG = "HINTS_STATE";
private static final String CLASS_NAME = InstructionsState.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 BitmapFont font;
// Overlay related fields.
HintsOverlayBase hintsOverlay;
// Button touch helper fields.
private boolean continueButtonTouched;
private int continueButtonTouchPointer;
public InstructionsState(NxtARCore core) throws IllegalArgumentException{
TextButtonStyle textButtonStyle;
FreeTypeFontGenerator fontGenerator;
FreeTypeFontParameter fontParameters;
NinePatch buttonEnabled9p;
NinePatch buttonDisabled9p;
NinePatch buttonPressed9p;
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;
hintsOverlay = ScenarioGlobals.getHintsOverlay();
// 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();
hintsOverlay.render(core.batch);
// 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.IN_GAME;
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.IN_GAME;
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.IN_GAME;
}
}
return true;
}else{
return false;
}
}
}

View File

@@ -49,8 +49,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
public class ScenarioEndSummaryState extends BaseState {
private static final String TAG = "AUTO_SUMMARY";
private static final String CLASS_NAME = AutomaticActionSummaryState.class.getSimpleName();
private static final String TAG = "SCENARIO_SUMMARY";
private static final String CLASS_NAME = ScenarioEndSummaryState.class.getSimpleName();
private static final String SHADER_PATH = "shaders/movingBckg/movingBckg";
// Helper fields.

View File

@@ -31,6 +31,7 @@ import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.math.Vector3;
public class RobotArmPositioningSystem extends EntityProcessingSystem {
@@ -82,6 +83,8 @@ public class RobotArmPositioningSystem extends EntityProcessingSystem {
Gdx.app.log(TAG, CLASS_NAME + ".process(): Started moving from " + Utils.vector2String(auto.startPoint) + " to " + Utils.vector2String(auto.endPoint));
}else autoMove(geometry, auto, collision);
input = null;
}else if(input instanceof GamepadUserInput){
tempGP = (GamepadUserInput) input;
@@ -89,12 +92,16 @@ public class RobotArmPositioningSystem extends EntityProcessingSystem {
if(!tempGP.oButton){
geometry.position.x += -tempGP.axisLeftY * STEP_SIZE;
geometry.position.y += tempGP.axisLeftX * STEP_SIZE;
if(Math.abs(tempGP.axisLeftX) < Ouya.STICK_DEADZONE && Math.abs(tempGP.axisLeftY) < Ouya.STICK_DEADZONE && Math.abs(tempGP.axisRightX) < Ouya.STICK_DEADZONE && Math.abs(tempGP.axisRightY) < Ouya.STICK_DEADZONE)
input = null;
}else{
endPoint = new Vector3(geometry.position.x, geometry.position.y, MAX_Z);
auto.startPoint.set(geometry.position);
auto.endPoint.set(endPoint);
auto.moving = true;
auto.forward = true;
input = null;
}
}else autoMove(geometry, auto, collision);
@@ -116,11 +123,11 @@ public class RobotArmPositioningSystem extends EntityProcessingSystem {
}
}else autoMove(geometry, auto, collision);
input = null;
}else
throw new ClassCastException("Input is not a valid UserInput instance.");
}
input = null;
}
private void autoMove(GeometryComponent geometry, AutomaticMovementComponent auto, CollisionDetectionComponent collision){

View File

@@ -28,14 +28,14 @@ public abstract class ProjectConstants{
public static final int EXIT_SUCCESS = 0;
public static final int EXIT_FAILURE = 1;
public static final boolean DEBUG = true;
public static final boolean DEBUG = false;
public static final int[] POWERS_OF_2 = {64, 128, 256, 512, 1024, 2048};
public static final float MAX_ABS_ROLL = 60.0f;
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;

View File

@@ -52,16 +52,25 @@ public abstract class Utils{
return (int)(Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
}
/**
* <p>Checks if the running device posseses and accelerometer and compass.</p>
*
* @return True when the device supports both sensors. False otherwise.
*/
public static boolean deviceHasOrientationSensors(){
return Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer) && Gdx.input.isPeripheralAvailable(Peripheral.Compass);
}
/**
* <p>Checks if the device's orientation is available and wihtin some arbitrary ranges.</p>
*
* @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);
boolean rollValid = false;
float azimuth, pitch;
if(rollValid){
if(deviceHasOrientationSensors()){
azimuth = Gdx.input.getAzimuth();
pitch = Gdx.input.getPitch();