Added instructions screen support.
This commit is contained in:
@@ -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>
|
||||
|
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/HintsOverlayBase.java
Normal file
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/HintsOverlayBase.java
Normal 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);
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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(){}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
326
src/ve/ucv/ciens/ccg/nxtar/states/InstructionsState.java
Normal file
326
src/ve/ucv/ciens/ccg/nxtar/states/InstructionsState.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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.
|
||||
|
@@ -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){
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
|
||||
|
Reference in New Issue
Block a user