5 Commits

Author SHA1 Message Date
0df8b37ddd Merge branch 'develop' 2014-05-15 12:10:47 -04:30
d481df0f96 Merge branch 'develop' 2014-04-04 10:27:33 -04:30
ae93dca1b9 Merge branch 'develop' 2014-03-14 15:16:50 -04:30
0fdef7c01c Merge branch 'develop' 2014-02-11 17:46:28 -04:30
481fe1f428 Merge branch 'release-14.01.10' 2014-01-09 08:24:50 -04:30
74 changed files with 2278 additions and 7487 deletions

View File

@@ -1,27 +1,4 @@
NxtAR: A generic software architecture for Augmented Reality based mobile robot control.
========================================================================================
NxtAR-core
==========
Core module
-----------
### Abstract ###
NxtAR is a generic software architecture for the development of Augmented Reality games
and applications centered around mobile robot control. This is a reference implementation
with support for [LEGO Mindstorms NXT][1] mobile robots.
### Module description ###
The core module comprises all the operating system independent classes that implemente the
base architecture and the different scenarios for the application. This implementation is
designed and built around the [LibGDX][2] and the [Artemis Entity-System Framework][3] libraries.
Currently there is one scenario titled *Bomb Game*.
### Module installation and usage. ###
The core module cannot be used directly. It is intended to be compiled with a LibGDX backend module.
[1]: http://www.lego.com/en-us/mindstorms/?domainredir=mindstorms.lego.com
[2]: http://libgdx.badlogicgames.com/
[3]: http://gamadu.com/artemis/
Modulo 2 de mi trabajo especial de grado.

BIN
libs/gdx-sources.jar Normal file

Binary file not shown.

BIN
libs/gdx.jar Normal file

Binary file not shown.

View File

@@ -5,7 +5,7 @@ import java.io.Serializable;
public class MotorEvent implements Serializable{
private static final long serialVersionUID = 9989L;
public enum motor_t {NONE, MOTOR_A, MOTOR_B, MOTOR_C, MOTOR_AC, RECENTER, ROTATE_90};
public enum motor_t {NONE, MOTOR_A, MOTOR_B, MOTOR_C, MOTOR_AC, RECENTER};
private motor_t motor;
private byte power;

View File

@@ -15,26 +15,21 @@
*/
package ve.ucv.ciens.ccg.nxtar;
import ve.ucv.ciens.ccg.nxtar.interfaces.ActionResolver;
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor;
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
import ve.ucv.ciens.ccg.nxtar.interfaces.AndroidFunctionalityWrapper;
import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread;
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.scenarios.ScenarioGlobals;
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;
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;
import ve.ucv.ciens.ccg.nxtar.states.PauseState;
import ve.ucv.ciens.ccg.nxtar.states.TabletMainMenuState;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenEquations;
import aurelienribon.tweenengine.primitives.MutableFloat;
@@ -56,7 +51,7 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram;
/**
* <p>Core of the application.</p>
*
* <p>This class has three basic responsibilities:</p>
* <p>This class has three basic resposibilities:</p>
* <ul>
* <li> Handling the main game loop.</li>
* <li> Starting and destroying the networking threads.</li>
@@ -78,7 +73,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), HINTS(6);
MAIN_MENU(0), IN_GAME(1), PAUSED(2), CALIBRATION(3);
private int value;
@@ -91,7 +86,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
}
public static int getNumStates(){
return 7;
return 4;
}
};
@@ -126,7 +121,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
/**
* <p>Wrapper around the Operating System methods.</p>
*/
private ActionResolver actionResolver;
private AndroidFunctionalityWrapper osFunction;
// Networking related fields.
/**
@@ -211,10 +206,10 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
// Check if the concrete application implements all required interfaces.
try{
this.actionResolver = (ActionResolver)concreteApp;
this.osFunction = (AndroidFunctionalityWrapper)concreteApp;
}catch(ClassCastException cc){
Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the Toaster interface. Toasting disabled.");
this.actionResolver = null;
this.osFunction = null;
}
try{
@@ -234,85 +229,46 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
* sets the application states.</p>
*/
public void create(){
try {
ScenarioGlobals.init(this);
} catch (IllegalArgumentException e) {
Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal argument initializing globals: ", e);
System.exit(1);
return;
} catch (InstantiationException e) {
Gdx.app.error(TAG, CLASS_NAME + ".create(): Instantiation exception initializing globals: ", e);
System.exit(1);
return;
} catch (IllegalAccessException e) {
Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal access exception initializing globals: ", e);
System.exit(1);
return;
}
// Set up rendering fields and settings.
batch = new SpriteBatch();
batch.enableBlending();
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
ShaderProgram.pedantic = false;
// Create the state objects.
states = new BaseState[game_states_t.getNumStates()];
try{
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);
System.exit(1);
return;
}
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);
System.exit(1);
return;
}
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);
System.exit(1);
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.IN_GAME.getValue()] = new InGameState(this);
states[game_states_t.PAUSED.getValue()] = new PauseState(this);
states[game_states_t.CALIBRATION.getValue()] = new CameraCalibrationState(this);
// Register controller listeners.
for(BaseState state : states){
Controllers.addListener(state);
}
// Set up the overlay font.
overlayX = -(Utils.getScreenWidthWithOverscan() / 2) + 10;
overlayY = (Utils.getScreenHeightWithOverscan() / 2) - 10;
// Set up rendering fields and settings.
batch = new SpriteBatch();
batch.enableBlending();
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
font = new BitmapFont();
font.setColor(1.0f, 1.0f, 0.0f, 1.0f);
if(!Ouya.runningOnOuya){
font.setScale(1.0f);
}else{
font.setScale(2.5f);
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
ShaderProgram.pedantic = false;
// Set up the overlay font.
if(ProjectConstants.DEBUG){
overlayX = -((Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN) / 2) + 10;
overlayY = ((Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN) / 2) - 10;
font = new BitmapFont();
font.setColor(1.0f, 1.0f, 0.0f, 1.0f);
if(!Ouya.runningOnOuya){
font.setScale(1.0f);
}else{
font.setScale(2.5f);
}
}
// Start networking.
actionResolver.enableMulticast();
osFunction.enableMulticast();
Gdx.app.debug(TAG, CLASS_NAME + ".create() :: Creating network threads");
serviceDiscoveryThread = ServiceDiscoveryThread.getInstance();
@@ -346,10 +302,11 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
fadeTexture = new Texture(pixmap);
pixmap.dispose();
alpha = new MutableFloat(0.0f);
alpha = new MutableFloat(0.0f);
fadeOut = Tween.to(alpha, 0, 0.5f).target(1.0f).ease(TweenEquations.easeInQuint);
fadeIn = Tween.to(alpha, 0, 0.5f).target(0.0f).ease(TweenEquations.easeInQuint);
fading = false;
fadeIn = Tween.to(alpha, 0, 0.5f).target(0.0f).ease(TweenEquations.easeInQuint);
fading = false;
// Set initial input handlers.
Gdx.input.setInputProcessor(states[currState.getValue()]);
@@ -370,10 +327,6 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
public void render(){
super.render();
// Load the assets.
if(!ScenarioGlobals.getEntityCreator().areEntitiesCreated())
ScenarioGlobals.getEntityCreator().updateAssetManager();
// If the current state set a value for nextState then switch to that state.
if(nextState != null){
states[currState.getValue()].onStateUnset();
@@ -432,111 +385,98 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
batch.setProjectionMatrix(pixelPerfectCamera.combined);
batch.begin();{
// Draw the FPS overlay.
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), overlayX, overlayY);
font.draw(batch, String.format("Total stream FPS: %d", videoThread.getFps()), overlayX, overlayY - font.getCapHeight() - 5);
font.draw(batch, String.format("Lost stream FPS: %d", videoThread.getLostFrames()), overlayX, overlayY - (2 * font.getCapHeight()) - 10);
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), overlayX, overlayY);
font.draw(batch, String.format("Total stream FPS: %d", videoThread.getFps()), overlayX, overlayY - font.getCapHeight() - 5);
font.draw(batch, String.format("Lost stream FPS: %d", videoThread.getLostFrames()), overlayX, overlayY - (2 * font.getCapHeight()) - 10);
font.draw(batch, String.format("Light sensor data: %d", sensorThread.getLightSensorReading()), overlayX, overlayY - (3 * font.getCapHeight()) - 15);
font.draw(batch, String.format("Device roll: %f", Gdx.input.getRoll()), overlayX, overlayY - (4 * font.getCapHeight()) - 20);
font.draw(batch, String.format("Device pitch: %f", Gdx.input.getPitch()), overlayX, overlayY - (5 * font.getCapHeight()) - 25);
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>
* <p>Pause a currently running thread. Pausing an already paused thread is a
* no op.</p>
*/
public void pause(){
if(videoThread != null)
videoThread.pause();
states[currState.getValue()].pause();
// TODO: Ignore pausing paused threads.
// TODO: Pause the other threads.
}
/**
* <p>Resumes the video streaming and the current state.</p>
* <p>Resume a currently paused thread. Resuming an already resumed thread is a
* no op.</p>
*/
public void resume(){
if(videoThread != null)
videoThread.play();
states[currState.getValue()].resume();
// TODO: Ignore resuming resumed threads.
// TODO: Resume the other threads.
}
/**
* <p>Clear graphic resources</p>
*/
public void dispose(){
// Dispose screens.
for(int i = 0; i < states.length; i++){
states[i].dispose();
}
// Finish network threads.
serviceDiscoveryThread.finish();
videoThread.finish();
robotThread.finish();
sensorThread.finish();
serviceDiscoveryThread = null;
videoThread = null;
robotThread = null;
sensorThread = null;
ServiceDiscoveryThread.freeInstance();
VideoStreamingThread.freeInstance();
RobotControlThread.freeInstance();
SensorReportThread.freeInstance();
// Dispose graphic objects.
fadeTexture.dispose();
batch.dispose();
font.dispose();
if(ProjectConstants.DEBUG){
font.dispose();
}
ScenarioGlobals.dispose();
// Dispose screens.
for(int i = 0; i < states.length; i++){
states[i].dispose();
}
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; APPLICATION EVENTS LISTENER INTERFACE METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
// TODO: Disable start game button until camera has been sucessfully calibrated.
// TODO: Add calibration listener callback.
/**
* <p>Callback used by the networking threads to notify sucessfull connections
* to the application</p>
*
* @param streamName The name of the thread notifying a connection.
*/
@Override
public synchronized void onNetworkStreamConnected(String streamName){
public synchronized void networkStreamConnected(String streamName){
Gdx.app.log(TAG, CLASS_NAME + ".networkStreamConnected() :: Stream " + streamName + " connected.");
connections += 1;
if(connections >= 3){
Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast.");
serviceDiscoveryThread.finish();
if(actionResolver != null) actionResolver.disableMulticast();
if(actionResolver != null) actionResolver.showShortToast("Client connected");
osFunction.disableMulticast();
osFunction.showShortToast("Client connected");
((MainMenuStateBase)states[game_states_t.MAIN_MENU.getValue()]).onClientConnected();
}
}
@Override
public void onAssetsLoaded(){
if(actionResolver != null) actionResolver.showShortToast("All assets sucessfully loaded.");
((MainMenuStateBase)states[game_states_t.MAIN_MENU.getValue()]).onAssetsLoaded();
}
@Override
public void onCameraCalibrated(){
if(actionResolver != null) actionResolver.showShortToast("Camera successfully calibrated.");
((MainMenuStateBase)states[game_states_t.MAIN_MENU.getValue()]).onCameraCalibrated();
}
/*;;;;;;;;;;;;;;;;;;
; HELPER METHODS ;
;;;;;;;;;;;;;;;;;;*/
/**
* <p>Show a toast message on screen using the {@link ActionResolver}.</p>
* <p>Show a toast message on screen using the O.S. functionality
* provider.</p>
* @param msg The message to show.
* @param longToast True for a lasting toast. False for a short toast.
*/
public void toast(String msg, boolean longToast){
if(actionResolver != null){
if(longToast) actionResolver.showLongToast(msg);
else actionResolver.showShortToast(msg);
if(osFunction != null){
if(longToast) osFunction.showLongToast(msg);
else osFunction.showShortToast(msg);
}
}
}

View File

@@ -1,76 +0,0 @@
/*
* 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.components;
import java.util.LinkedList;
import java.util.List;
import com.artemis.Component;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.utils.AnimationController;
public class AnimationComponent extends Component {
public AnimationController controller;
public AnimationController collisionController;
public List<String> animationsIds;
public int current;
public int next;
public boolean loop;
public AnimationComponent(ModelInstance instance, ModelInstance collisionInstance){
this(instance, -1, false, collisionInstance);
}
public AnimationComponent(ModelInstance instance) throws IllegalArgumentException{
this(instance, -1, false);
}
public AnimationComponent(ModelInstance instance, int next) throws IllegalArgumentException{
this(instance, next, false);
}
public AnimationComponent(ModelInstance instance, int next, boolean loop) throws IllegalArgumentException{
if(instance == null)
throw new IllegalArgumentException("Instance is null.");
else if(next > instance.animations.size)
throw new IllegalArgumentException("Next is greater than the number of animations for this model.");
controller = new AnimationController(instance);
collisionController = null;
animationsIds = new LinkedList<String>();
current = -1;
this.next = next;
this.loop = loop;
for(int i = 0; i < instance.animations.size; i++){
animationsIds.add(instance.animations.get(i).id);
}
}
public AnimationComponent(ModelInstance instance, int next, boolean loop, ModelInstance collisionInstance) throws IllegalArgumentException{
this(instance, next, loop);
if(instance.animations.size != collisionInstance.animations.size)
throw new IllegalArgumentException("Animation number doesn't match between render model and collision model.");
for(int i = 0; i < instance.animations.size; i++){
if(!instance.animations.get(i).id.contentEquals(collisionInstance.animations.get(i).id))
throw new IllegalArgumentException("Animations don't match between render model and collision model.");
}
collisionController = new AnimationController(collisionInstance);
}
}

View File

@@ -1,51 +0,0 @@
/*
* 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.components;
import com.artemis.Component;
import com.badlogic.gdx.math.Vector3;
public class AutomaticMovementComponent extends Component{
public boolean moving;
public boolean forward;
public float distance;
public Vector3 startPoint;
public Vector3 endPoint;
public AutomaticMovementComponent(Vector3 startPoint, Vector3 endPoint, boolean moving){
this.moving = moving;
this.forward = true;
this.distance = 0.0f;
this.startPoint = startPoint;
this.endPoint = endPoint;
}
public AutomaticMovementComponent(Vector3 startPoint, Vector3 endPoint){
this(startPoint, endPoint, false);
}
public AutomaticMovementComponent(boolean moving){
this(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(), moving);
}
public AutomaticMovementComponent(Vector3 endPoint){
this(new Vector3(0.0f, 0.0f, 0.0f), endPoint, false);
}
public AutomaticMovementComponent(){
this(false);
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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.components;
import com.artemis.Component;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
public class CollisionModelComponent extends Component {
public ModelInstance instance;
public CollisionModelComponent(Model model) throws IllegalArgumentException{
if(model == null)
throw new IllegalArgumentException("Model is null.");
this.instance = new ModelInstance(model);
}
public CollisionModelComponent(ModelInstance instance) throws IllegalArgumentException{
if(instance == null)
throw new IllegalArgumentException("Instance is null.");
this.instance = instance;
}
}

View File

@@ -1,30 +0,0 @@
/*
* 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.components;
import com.artemis.Component;
import com.badlogic.gdx.graphics.g3d.Environment;
public class EnvironmentComponent extends Component {
public Environment environment;
public EnvironmentComponent(Environment environment) throws IllegalArgumentException{
if(environment == null)
throw new IllegalArgumentException("Environment is null.");
this.environment = environment;
}
}

View File

@@ -1,129 +0,0 @@
/*
* 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.components;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenEquations;
import aurelienribon.tweenengine.primitives.MutableFloat;
import com.artemis.Component;
import com.badlogic.gdx.graphics.Color;
public class FadeEffectComponent extends Component{
private MutableFloat alpha;
private Tween fadeIn;
private Tween fadeOut;
public Color color;
/**
* <p>Creates a fade to/from white depending on the parameter.</p>
*
* @param fadeIn True to create a fade FROM white, false for a fade TO white.
*/
public FadeEffectComponent(boolean fadeIn){
if(fadeIn){
this.alpha = new MutableFloat(1.0f);
this.fadeIn = Tween.to(alpha, 0, 2.0f).target(0.0f).ease(TweenEquations.easeInQuint);
this.fadeOut = null;
}else{
this.alpha = new MutableFloat(0.0f);
this.fadeOut = Tween.to(alpha, 0, 2.5f).target(1.0f).ease(TweenEquations.easeInQuint);
this.fadeIn = null;
}
color = new Color(Color.WHITE);
}
/**
* <p>Creates a fade effect with the desired parameters.</p>
*
* @param fadeIn True to create a fade FROM color, false for a fade TO color.
* @param color The color of the effect.
*/
public FadeEffectComponent(boolean fadeIn, Color color){
this(fadeIn);
this.color.set(color);
}
/**
* <p>Creates a fade out effect of the desired color.</p>
*
* @param color The color of the effect.
*/
public FadeEffectComponent(Color color){
this(false, color);
}
/**
* <p>Creates a white fade out effect.</p>
*/
public FadeEffectComponent(){
this(false);
}
/**
* <p>The current transparency of the effect.</p>
*
* @return The transparency.
*/
public float getFloatValue(){
return alpha.floatValue();
}
/**
* <p>Interpolates the transparency of the effect by the given delta time in seconds.</p>
*
* @param delta
*/
public void update(float delta){
if(fadeIn != null)
fadeIn.update(delta);
if(fadeOut != null)
fadeOut.update(delta);
}
/**
* <p>Initializes the effect.</p>
*/
public void startEffect(){
if(fadeIn != null)
fadeIn.start();
if(fadeOut != null)
fadeOut.start();
}
/**
* @return True if the effect has been initialized. False otherwise.
*/
public boolean isEffectStarted(){
return fadeIn != null ? fadeIn.isStarted() : fadeOut.isStarted();
}
/**
* @return True if this effect is a fade in. False if it is a fade out.
*/
public boolean isEffectFadeIn(){
return fadeIn != null;
}
/**
* @return True if the effect's interpolation is over. False otherwise.
*/
public boolean isEffectFinished(){
return fadeIn != null ? fadeIn.isFinished() : fadeOut.isFinished();
}
}

View File

@@ -18,18 +18,11 @@ package ve.ucv.ciens.ccg.nxtar.components;
import com.artemis.Component;
public class MarkerCodeComponent extends Component {
public int code;
public boolean enabled;
public int code;
public MarkerCodeComponent(int code) throws IllegalArgumentException{
if(code < 0 || code > 1024)
throw new IllegalArgumentException("Marker code must be between [0, 1024].");
this.code = code;
this.enabled = true;
}
public MarkerCodeComponent(int code, boolean enabled){
this(code);
this.enabled = enabled;
}
}

View File

@@ -16,11 +16,12 @@
package ve.ucv.ciens.ccg.nxtar.components;
import com.artemis.Component;
import com.badlogic.gdx.graphics.Mesh;
public class CollisionDetectionComponent extends Component {
public boolean colliding;
public CollisionDetectionComponent(){
this.colliding = false;
public class MeshComponent extends Component {
public Mesh model;
public MeshComponent(Mesh model){
this.model = model;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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.components;
import com.artemis.Component;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
public class RenderModelComponent extends Component {
public ModelInstance instance;
public RenderModelComponent(Model model) throws IllegalArgumentException{
if(model == null)
throw new IllegalArgumentException("Model is null.");
this.instance = new ModelInstance(model);
}
public RenderModelComponent(ModelInstance instance) throws IllegalArgumentException{
if(instance == null)
throw new IllegalArgumentException("Instance is null.");
this.instance = instance;
}
}

View File

@@ -15,15 +15,16 @@
*/
package ve.ucv.ciens.ccg.nxtar.components;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase;
import com.artemis.Component;
import com.badlogic.gdx.graphics.g3d.Shader;
public class ShaderComponent extends Component{
public Shader shader;
public class ShaderComponent extends Component {
public CustomShaderBase shader;
public ShaderComponent(Shader shader) throws IllegalArgumentException{
public ShaderComponent(CustomShaderBase shader) throws IllegalArgumentException{
if(shader == null)
throw new IllegalArgumentException("Shader is null.");
throw new IllegalArgumentException("Shader cannot be null.");
this.shader = shader;
}

View File

@@ -1,30 +0,0 @@
/*
* 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.components;
import com.artemis.Component;
public class VisibilityComponent extends Component {
public boolean visible;
public VisibilityComponent(){
this.visible = true;
}
public VisibilityComponent(boolean visibility){
this.visible = visibility;
}
}

View File

@@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ve.ucv.ciens.ccg.nxtar.systems;
package ve.ucv.ciens.ccg.nxtar.entities;
import com.artemis.Aspect;
import com.artemis.Entity;
import com.artemis.systems.EntityProcessingSystem;
public abstract class GameLogicSystemBase extends EntityProcessingSystem {
public GameLogicSystemBase(Aspect aspect){
super(aspect);
public class BombGameEntityCreator extends EntityCreatorBase {
public BombGameEntityCreator(){
// TODO: Empty constructor.
}
@Override
protected abstract void process(Entity e);
public void createAllEntities() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
}

View File

@@ -15,72 +15,19 @@
*/
package ve.ucv.ciens.ccg.nxtar.entities;
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
import com.artemis.World;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.utils.Disposable;
/**
*
*/
public abstract class EntityCreatorBase implements Disposable{
protected World world = null;
protected ApplicationEventsListener core = null;
protected boolean entitiesCreated = false;
protected AssetManager manager = null;
public abstract class EntityCreatorBase {
protected World world;
/**
* <p>Sets the Artemis {@link World} to use to create entities.</p>
*
* @param world The Artemis {@link World}.
* @throws IllegalArgumentException if world is null.
*/
public final void setWorld(World world) throws IllegalArgumentException{
public void setWorld(World world) throws IllegalArgumentException{
if(world == null)
throw new IllegalArgumentException("World cannot be null.");
this.world = world;
}
/**
* <p>Sets the application core to listen for asset loading events.</p>
*
* @param core The application core to be used as listener.
* @throws IllegalArgumentException if core is null.
*/
public final void setCore(NxtARCore core) throws IllegalArgumentException{
if(core == null) throw new IllegalArgumentException("Core is null.");
this.core = core;
}
public abstract void createAllEntities();
/**
* <p> Updates the state of the {@link AssetManager}.</p>
*
* @return true if the {@link AssetManager} has finished loading.
*/
public abstract boolean updateAssetManager();
/**
* <p>Unloads all assets loaded for the scenario.</p>
*/
public abstract void dispose();
/**
* @return true if the createAllEntities method has been called.
*/
public boolean areEntitiesCreated(){
return entitiesCreated;
}
/**
* <p>Creates all entities for a game scenario.</p>
*/
protected abstract void createAllEntities();
/**
* <p>Recreates all entities in the game.</p>
*/
public abstract void resetAllEntities();
}

View File

@@ -0,0 +1,93 @@
/*
* 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.entities;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader;
import com.artemis.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder;
import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector3;
public class MarkerTestEntityCreator extends EntityCreatorBase {
private static final String TAG = "MARKER_TEST_ENTITY_CREATOR";
private static final String CLASS_NAME = MarkerTestEntityCreator.class.getSimpleName();
private Mesh markerMesh;
private CustomShaderBase phongShader;
@Override
public void createAllEntities() {
MeshBuilder builder;
Matrix3 identity = new Matrix3().idt();
Entity marker;
// Create mesh.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes.");
builder = new MeshBuilder();
builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_TRIANGLES);{
builder.setColor(1.0f, 1.0f, 1.0f, 1.0f);
Vector3 v00 = new Vector3(-0.5f, -0.5f, 0.0f);
Vector3 v10 = new Vector3(-0.5f, 0.5f, 0.0f);
Vector3 v11 = new Vector3( 0.5f, 0.5f, 0.0f);
Vector3 v01 = new Vector3( 0.5f, -0.5f, 0.0f);
Vector3 n = new Vector3(0.0f, 1.0f, 0.0f);
builder.patch(v00, v10, v11, v01, n, 10, 10);
}markerMesh = builder.end();
// Load the phong shader.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Loading the phong shader.");
try{
phongShader = new SingleLightPhongShader().loadShader();
}catch(ShaderFailedToLoadException se){
Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + se.getMessage());
Gdx.app.exit();
}
// Create the entities.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites.");
marker = world.createEntity();
marker.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f)));
marker.addComponent(new MeshComponent(markerMesh));
marker.addComponent(new ShaderComponent(phongShader));
marker.addComponent(new MarkerCodeComponent(213));
// Add the entities to the world.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world.");
marker.addToWorld();
}
@Override
public void dispose() {
if(phongShader != null && phongShader.getShaderProgram() != null)
phongShader.getShaderProgram().dispose();
if(markerMesh != null)
markerMesh.dispose();
}
}

View File

@@ -0,0 +1,134 @@
/*
* 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.entities;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader;
import com.artemis.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder;
import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector3;
public class TestGameEntityCreator extends EntityCreatorBase {
private static final String TAG = "TEST_ENTITY_CREATOR";
private static final String CLASS_NAME = TestGameEntityCreator.class.getSimpleName();
private MeshBuilder builder;
private Mesh sphereMesh;
private Mesh cubeMesh;
private Mesh capsuleMesh;
private CustomShaderBase singleLightPhongShader;
@Override
public void createAllEntities() {
Matrix3 identity = new Matrix3();
Entity sphere;
Entity cube;
Entity capsule1;
Entity capsule2;
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Started.");
identity.idt();
// Create the sphere.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes.");
builder = new MeshBuilder();
builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_TRIANGLES);{
builder.setColor(1.0f, 1.0f, 1.0f, 1.0f);
builder.sphere(1.0f, 1.0f, 1.0f, 10, 10);
}sphereMesh = builder.end();
// Create the cube.
builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_TRIANGLES);{
builder.setColor(0.2f, 0.5f, 1.0f, 1.0f);
builder.box(0.5f, 0.5f, 0.5f);
}cubeMesh = builder.end();
// Create the capsule.
builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_TRIANGLES);{
builder.setColor(1.0f, 1.0f, 1.0f, 1.0f);
builder.capsule(0.25f, 0.5f, 10);
}capsuleMesh = builder.end();
// Load the phong shader.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Loading the phong shader.");
try{
singleLightPhongShader = new SingleLightPhongShader().loadShader();
}catch(ShaderFailedToLoadException se){
Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + se.getMessage());
Gdx.app.exit();
}
// Create the entities.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites.");
sphere = world.createEntity();
sphere.addComponent(new GeometryComponent(new Vector3(0.5f, 0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f)));
sphere.addComponent(new MeshComponent(sphereMesh));
sphere.addComponent(new ShaderComponent(singleLightPhongShader));
cube = world.createEntity();
cube.addComponent(new GeometryComponent(new Vector3(-0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f)));
cube.addComponent(new MeshComponent(cubeMesh));
cube.addComponent(new ShaderComponent(singleLightPhongShader));
capsule1 = world.createEntity();
capsule1.addComponent(new GeometryComponent(new Vector3(-0.5f, 0.5f, 0.0f), identity, new Vector3(1.5f, 1.0f, 1.0f)));
capsule1.addComponent(new MeshComponent(capsuleMesh));
capsule1.addComponent(new ShaderComponent(singleLightPhongShader));
capsule2 = world.createEntity();
capsule2.addComponent(new GeometryComponent(new Vector3(0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.5f, 1.0f)));
capsule2.addComponent(new MeshComponent(capsuleMesh));
capsule2.addComponent(new ShaderComponent(singleLightPhongShader));
// Add the entities to the world.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world.");
sphere.addToWorld();
cube.addToWorld();
capsule1.addToWorld();
capsule2.addToWorld();
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Finished.");
}
@Override
public void dispose() {
if(singleLightPhongShader != null && singleLightPhongShader.getShaderProgram() != null)
singleLightPhongShader.getShaderProgram().dispose();
if(sphereMesh != null)
sphereMesh.dispose();
if(cubeMesh != null)
cubeMesh.dispose();
if(capsuleMesh != null)
capsuleMesh.dispose();
}
}

View File

@@ -13,8 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ve.ucv.ciens.ccg.nxtar.scenarios;
package ve.ucv.ciens.ccg.nxtar.exceptions;
public abstract class SummaryBase{
public abstract void reset();
}
public class ShaderFailedToLoadException extends Exception {
private static final long serialVersionUID = 9989L;
public ShaderFailedToLoadException(String msg){
super(msg);
}
}

View File

@@ -27,47 +27,22 @@ public class CustomPerspectiveCamera extends PerspectiveCamera{
private final Vector3 tmp = new Vector3();
public CustomPerspectiveCamera(float fieldOfView, float viewportWidth, float viewportHeight){
super(fieldOfView, viewportWidth, viewportHeight);
this.fieldOfView = fieldOfView;
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
update();
}
public void update(Matrix4 customProjection){
this.update(customProjection, true);
}
public void update(Matrix4 customProjection, boolean updateFrustum){
projection.set(customProjection);
view.setToLookAt(position, tmp.set(position).add(direction), up);
combined.set(projection).mul(view);
combined.set(projection);
Matrix4.mul(combined.val, view.val);
if(updateFrustum){
invProjectionView.set(combined).inv();
invProjectionView.set(combined);
Matrix4.inv(invProjectionView.val);
frustum.update(invProjectionView);
}
}
public void setCustomARProjectionMatrix(final float focalPointX, final float focalPointY, final float cameraCenterX, final float cameraCenterY, final float near, final float far, final float w, final float h){
final float FAR_PLUS_NEAR = far + near;
final float FAR_LESS_NEAR = far - near;
projection.val[Matrix4.M00] = -2.0f * focalPointX / w;
projection.val[Matrix4.M10] = 0.0f;
projection.val[Matrix4.M20] = 0.0f;
projection.val[Matrix4.M30] = 0.0f;
projection.val[Matrix4.M01] = 0.0f;
projection.val[Matrix4.M11] = 2.0f * focalPointY / h;
projection.val[Matrix4.M21] = 0.0f;
projection.val[Matrix4.M31] = 0.0f;
projection.val[Matrix4.M02] = 2.0f * cameraCenterX / w - 1.0f;
projection.val[Matrix4.M12] = 2.0f * cameraCenterY / h - 1.0f;
projection.val[Matrix4.M22] = -FAR_PLUS_NEAR / FAR_LESS_NEAR;
projection.val[Matrix4.M32] = -1.0f;
projection.val[Matrix4.M03] = 0.0f;
projection.val[Matrix4.M13] = 0.0f;
projection.val[Matrix4.M23] = -2.0f * far * near / FAR_LESS_NEAR;
projection.val[Matrix4.M33] = 0.0f;
}
}

View File

@@ -0,0 +1,162 @@
/*
* 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.graphics;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector3;
/**
* <p>A 3D light source.</p>
*/
public class LightSource{
private Vector3 position;
private Color ambientColor;
private Color diffuseColor;
private Color specularColor;
private float shinyness;
/**
* <p>Creates a default white light source positioned at (0,0,0).</p>
*/
public LightSource(){
position = new Vector3(0.0f, 0.0f, 0.0f);
ambientColor = new Color(0.15f, 0.15f, 0.15f, 1.0f);
diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
specularColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
ambientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
shinyness = 10.0f;
}
/**
* <p>Creates a white light source at the specified position.</p>
*
* @param position The location of the light source.
*/
public LightSource(Vector3 position){
this.position = new Vector3();
this.position.set(position);
ambientColor = new Color(0.15f, 0.15f, 0.15f, 1.0f);
diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
specularColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
ambientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
shinyness = 10.0f;
}
/**
* <p>Creates a custom light source.</p>
*
* @param position The location of the light source.
* @param ambientColor
* @param diffuseColor
* @param specularColor
* @param shinyness The shinyness component. Must be between (0.0, 128.0].
* @throws IllegalArgumentException When shinyness is outside the valid range.
*/
public LightSource(Vector3 position, Color ambientColor, Color diffuseColor, Color specularColor, float shinyness) throws IllegalArgumentException {
if(shinyness <= 0.0 || shinyness > 128.0)
throw new IllegalArgumentException("Shinyness must be between (0.0, 128.0].");
this.position = new Vector3();
this.ambientColor = new Color();
this.diffuseColor = new Color();
this.ambientColor = new Color();
this.specularColor = new Color();
this.position.set(position);
this.ambientColor.set(ambientColor);
this.diffuseColor.set(diffuseColor);
this.specularColor.set(specularColor);
this.shinyness = shinyness;
}
public LightSource(LightSource light){
this.position = new Vector3();
this.ambientColor = new Color();
this.diffuseColor = new Color();
this.ambientColor = new Color();
this.specularColor = new Color();
set(light);
}
public void set(LightSource light){
this.position.set(light.getPosition());
this.ambientColor.set(light.getAmbientColor());
this.diffuseColor.set(light.getDiffuseColor());
this.specularColor.set(light.getSpecularColor());
this.shinyness = light.shinyness;
}
public void setPosition(float x, float y, float z){
position.set(x, y, z);
}
public void setPosition(Vector3 position){
this.position.set(position);
}
public void setAmbientColor(float r, float g, float b, float a){
ambientColor.set(r, g, b, a);
}
public void setAmbientColor(Color ambientColor){
this.ambientColor.set(ambientColor);
}
public void setDiffuseColor(float r, float g, float b, float a){
diffuseColor.set(r, g, b, a);
}
public void setdiffuseColor(Color diffuseColor){
this.diffuseColor.set(diffuseColor);
}
public void setSpecularColor(float r, float g, float b, float a){
specularColor.set(r, g, b, a);
}
public void setSpecularColor(Color specularColor){
this.specularColor.set(specularColor);
}
public void setShinyness(float shinyness) throws IllegalArgumentException {
if(shinyness <= 0.0 || shinyness > 128.0)
throw new IllegalArgumentException("Shinyness must be between (0.0, 128.0].");
this.shinyness = shinyness;
}
public Vector3 getPosition(){
return position;
}
public Color getAmbientColor(){
return ambientColor;
}
public Color getDiffuseColor(){
return diffuseColor;
}
public Color getSpecularColor(){
return specularColor;
}
public float getShinyness(){
return shinyness;
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.graphics;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
public abstract class RenderParameters {
private static Matrix4 modelViewProjection;
private static Matrix4 geometricTransformation;
private static Vector3 eyePosition;
private static LightSource lightSource1;
private static LightSource lightSource2;
static{
modelViewProjection = new Matrix4();
geometricTransformation = new Matrix4();
eyePosition = new Vector3(0.0f, 0.0f, 1.4142f);
lightSource1 = new LightSource();
lightSource2 = new LightSource();
}
public static synchronized void setModelViewProjectionMatrix(Matrix4 modelViewMatrix){
modelViewProjection.set(modelViewMatrix);
}
public static synchronized void setTransformationMatrix(Matrix4 transformationMatrix){
geometricTransformation.set(transformationMatrix);
}
public static synchronized void setEyePosition(Vector3 newEyePostition){
eyePosition.set(newEyePostition);
}
public static synchronized void setLightSource1(LightSource newLightSource1){
lightSource1.set(newLightSource1);
}
public static synchronized void setLightSource2(LightSource newLightSource2){
lightSource2.set(newLightSource2);
}
public static synchronized Matrix4 getModelViewProjectionMatrix(){
return modelViewProjection;
}
public static synchronized Matrix4 getTransformationMatrix(){
return geometricTransformation;
}
public static synchronized Vector3 getEyePosition(){
return eyePosition;
}
public static synchronized LightSource getLightSource1(){
return lightSource1;
}
public static synchronized LightSource getLightSource2(){
return lightSource2;
}
}

View File

@@ -13,26 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ve.ucv.ciens.ccg.nxtar.components;
package ve.ucv.ciens.ccg.nxtar.graphics.shaders;
import com.artemis.Component;
import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException;
/**
* Tag class.
*/
public abstract class PlayerComponentBase extends Component {
public static final String PLAYER_GROUP = "PLAYER";
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public boolean gameFinished;
public boolean victory;
public abstract class CustomShaderBase{
protected ShaderProgram shaderProgram;
public PlayerComponentBase(){
this.gameFinished = false;
this.victory = false;
}
public abstract CustomShaderBase loadShader() throws ShaderFailedToLoadException;
public void reset(){
this.gameFinished = false;
this.victory = false;
public abstract void setUniforms();
public ShaderProgram getShaderProgram(){
return this.shaderProgram;
}
}

View File

@@ -1,245 +0,0 @@
/*
* 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.graphics.shaders;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Renderable;
import com.badlogic.gdx.graphics.g3d.Shader;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.GdxRuntimeException;
public class DirectionalLightPerPixelShader implements Shader{
private static final int MAX_NUM_BONES = 4;
private static final Matrix4 IDENTITY = new Matrix4();
private static final String VERTEX_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_vert.glsl";
private static final String FRAGMENT_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_frag.glsl";
private static final String INCLUDE_SKINNING = "#define SKINNING\n";
private static final float DEFAULT_SHININESS = 50.0f;
private static final Vector3 DEFAULT_LIGHT = new Vector3(1, 1, 1);
private ShaderProgram skinningProgram;
private ShaderProgram baseProgram;
private Camera camera;
private RenderContext context;
private Matrix4 normalMatrix;
// Uniform locations.
private int[] u_geomTrans;
private int[] u_projTrans;
private int[] u_lightPos;
private int[] u_lightDiffuse;
private int[] u_specular;
private int[] u_ambient;
private int[] u_shiny;
private int[] u_cameraPos;
private int[] u_materialDiffuse;
private int[] u_normalMatrix;
private int[] u_bones;
public DirectionalLightPerPixelShader(){
skinningProgram = null;
baseProgram = null;
camera = null;
context = null;
}
@Override
public void init() throws GdxRuntimeException{
normalMatrix = new Matrix4().idt();
u_bones = new int[MAX_NUM_BONES];
// Compile the shader.
String vertexCode = Gdx.files.internal(VERTEX_SHADER_PATH).readString();
String fragmentCode = Gdx.files.internal(FRAGMENT_SHADER_PATH).readString();
skinningProgram = new ShaderProgram(INCLUDE_SKINNING + vertexCode, fragmentCode);
baseProgram = new ShaderProgram(vertexCode, fragmentCode);
if(!skinningProgram.isCompiled())
throw new GdxRuntimeException(skinningProgram.getLog());
if(!baseProgram.isCompiled())
throw new GdxRuntimeException(baseProgram.getLog());
// Create uniform locations.
u_projTrans = new int[2];
u_geomTrans = new int[2];
u_lightPos = new int[2];
u_lightDiffuse = new int[2];
u_specular = new int[2];
u_ambient = new int[2];
u_shiny = new int[2];
u_cameraPos = new int[2];
u_materialDiffuse = new int[2];
u_normalMatrix = new int[2];
// Cache uniform locations.
u_projTrans [0] = skinningProgram.getUniformLocation("u_projTrans");
u_geomTrans [0] = skinningProgram.getUniformLocation("u_geomTrans");
u_lightPos [0] = skinningProgram.getUniformLocation("u_lightPos");
u_lightDiffuse [0] = skinningProgram.getUniformLocation("u_lightDiffuse");
u_specular [0] = skinningProgram.getUniformLocation("u_specular");
u_ambient [0] = skinningProgram.getUniformLocation("u_ambient");
u_shiny [0] = skinningProgram.getUniformLocation("u_shiny");
u_cameraPos [0] = skinningProgram.getUniformLocation("u_cameraPos");
u_materialDiffuse [0] = skinningProgram.getUniformLocation("u_materialDiffuse");
u_normalMatrix [0] = skinningProgram.getUniformLocation("u_normalMatrix");
u_projTrans [1] = baseProgram.getUniformLocation("u_projTrans");
u_geomTrans [1] = baseProgram.getUniformLocation("u_geomTrans");
u_lightPos [1] = baseProgram.getUniformLocation("u_lightPos");
u_lightDiffuse [1] = baseProgram.getUniformLocation("u_lightDiffuse");
u_specular [1] = baseProgram.getUniformLocation("u_specular");
u_ambient [1] = baseProgram.getUniformLocation("u_ambient");
u_shiny [1] = baseProgram.getUniformLocation("u_shiny");
u_cameraPos [1] = baseProgram.getUniformLocation("u_cameraPos");
u_materialDiffuse [1] = baseProgram.getUniformLocation("u_materialDiffuse");
u_normalMatrix [1] = baseProgram.getUniformLocation("u_normalMatrix");
for(int i = 0; i < MAX_NUM_BONES; i++){
u_bones[i] = skinningProgram.getUniformLocation("u_bone" + Integer.toString(i));
}
}
@Override
public void dispose(){
if(skinningProgram != null) skinningProgram.dispose();
if(baseProgram != null) baseProgram.dispose();
}
@Override
public int compareTo(Shader other){
return 0;
}
@Override
public boolean canRender(Renderable renderable){
// Easier to always return true. Missing material properties are replaced by
// default values during render.
return true;
}
@Override
public void begin(Camera camera, RenderContext context) throws GdxRuntimeException{
if(this.camera != null || this.context != null)
throw new GdxRuntimeException("Called begin twice before calling end.");
this.camera = camera;
this.context = context;
// Set render context.
this.context.setDepthTest(GL20.GL_LEQUAL);
this.context.setDepthMask(true);
}
@Override
public void render(Renderable renderable){
ShaderProgram program;
int index;
boolean bonesEnabled;
Vector3 lightPosition;
Color diffuseLightColor;
Color diffuseColor;
Color specularColor;
Color ambientColor;
float shininess;
// Get material colors.
if(renderable.environment != null && renderable.environment.directionalLights != null && renderable.environment.directionalLights.size >= 1){
lightPosition = renderable.environment.directionalLights.get(0).direction;
diffuseLightColor = renderable.environment.directionalLights.get(0).color;
}else{
lightPosition = DEFAULT_LIGHT;
diffuseLightColor = Color.WHITE;
}
if(renderable.material.has(ColorAttribute.Diffuse))
diffuseColor = ((ColorAttribute)renderable.material.get(ColorAttribute.Diffuse)).color;
else
diffuseColor = Color.WHITE;
if(renderable.material.has(ColorAttribute.Specular))
specularColor = ((ColorAttribute)renderable.material.get(ColorAttribute.Specular)).color;
else
specularColor = Color.BLACK;
if(renderable.environment != null && renderable.environment.has(ColorAttribute.AmbientLight))
ambientColor = ((ColorAttribute)renderable.environment.get(ColorAttribute.AmbientLight)).color;
else
ambientColor = Color.BLACK;
if(renderable.material.has(FloatAttribute.Shininess))
shininess = ((FloatAttribute)renderable.material.get(FloatAttribute.Shininess)).value;
else
shininess = DEFAULT_SHININESS;
if(renderable.mesh.getVertexAttribute(VertexAttributes.Usage.BoneWeight) != null){
program = skinningProgram;
index = 0;
bonesEnabled = true;
}else{
program = baseProgram;
index = 1;
bonesEnabled = false;
}
program.begin();
// Set camera dependant uniforms.
program.setUniformMatrix(u_projTrans[index], this.camera.combined);
program.setUniformf(u_cameraPos[index], this.camera.position);
// Set model dependant uniforms.
program.setUniformMatrix(u_geomTrans[index], renderable.worldTransform);
program.setUniformMatrix(u_normalMatrix[index], normalMatrix.set(renderable.worldTransform).toNormalMatrix());
program.setUniformf(u_lightPos[index], lightPosition);
program.setUniformf(u_lightDiffuse[index], diffuseLightColor);
program.setUniformf(u_materialDiffuse[index], diffuseColor);
program.setUniformf(u_specular[index], specularColor);
program.setUniformf(u_ambient[index], ambientColor);
program.setUniformf(u_shiny[index], shininess);
// Set the bones uniforms.
if(bonesEnabled){
for(int i = 0; i < MAX_NUM_BONES; i++){
if(renderable.bones != null && i < renderable.bones.length && renderable.bones[i] != null)
skinningProgram.setUniformMatrix(u_bones[i], renderable.bones[i]);
else
skinningProgram.setUniformMatrix(u_bones[i], IDENTITY);
}
}
renderable.mesh.render(program, renderable.primitiveType, renderable.meshPartOffset, renderable.meshPartSize);
program.end();
}
@Override
public void end(){
this.camera = null;
this.context = null;
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.graphics.shaders;
import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException;
import ve.ucv.ciens.ccg.nxtar.graphics.LightSource;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public class SingleLightPhongShader extends CustomShaderBase{
private static String VERTEX_SHADER_PATH = "shaders/singleDiffuseLight/singleDiffuseLight_vert.glsl";
private static String FRAGMENT_SHADER_PATH = "shaders/singleDiffuseLight/singleDiffuseLight_frag.glsl";
@Override
public SingleLightPhongShader loadShader() throws ShaderFailedToLoadException{
shaderProgram = new ShaderProgram(Gdx.files.internal(VERTEX_SHADER_PATH), Gdx.files.internal(FRAGMENT_SHADER_PATH));
if(!shaderProgram.isCompiled()){
throw new ShaderFailedToLoadException("SingleLightPerPixelPhongShader failed to load.\n" + shaderProgram.getLog());
}
return this;
}
@Override
public void setUniforms(){
LightSource light = RenderParameters.getLightSource1();
float[] diffuseColor = {light.getDiffuseColor().r, light.getDiffuseColor().g, light.getDiffuseColor().b, light.getDiffuseColor().a};
float[] ambientColor = {light.getAmbientColor().r, light.getAmbientColor().g, light.getAmbientColor().b, light.getAmbientColor().a};
float[] specularColor = {light.getSpecularColor().r, light.getSpecularColor().g, light.getSpecularColor().b, light.getSpecularColor().a};
float[] position = {light.getPosition().x, light.getPosition().y, light.getPosition().z, 0.0f};
float[] shinyness = {light.getShinyness()};
shaderProgram.setUniformMatrix("u_projTrans", RenderParameters.getModelViewProjectionMatrix());
shaderProgram.setUniformMatrix("u_geomTrans", RenderParameters.getTransformationMatrix());
shaderProgram.setUniform4fv("u_lightPos", position, 0, 4);
shaderProgram.setUniform4fv("u_lightDiffuse", diffuseColor, 0, 4);
shaderProgram.setUniform4fv("u_specular", specularColor, 0, 4);
shaderProgram.setUniform4fv("u_ambient", ambientColor, 0, 4);
shaderProgram.setUniform1fv("u_shiny", shinyness, 0, 1);
shaderProgram.setUniformf("u_cameraPos", RenderParameters.getEyePosition());
}
}

View File

@@ -1,32 +0,0 @@
/*
* 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.input;
public class GamepadUserInput extends UserInput {
public float axisLeftX;
public float axisLeftY;
public float axisRightX;
public float axisRightY;
public boolean oButton;
public GamepadUserInput(){
this.axisLeftX = 0.0f;
this.axisLeftY = 0.0f;
this.axisRightX = 0.0f;
this.axisRightY = 0.0f;
this.oButton = false;
}
}

View File

@@ -1,32 +0,0 @@
/*
* 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.input;
public class KeyboardUserInput extends UserInput {
public boolean keyLeft;
public boolean keyRight;
public boolean keyUp;
public boolean keyDown;
public boolean keySpace;
public KeyboardUserInput(){
this.keyLeft = false;
this.keyRight = false;
this.keyUp = false;
this.keyDown = false;
this.keySpace = false;
}
}

View File

@@ -1,34 +0,0 @@
/*
* 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.input;
import com.badlogic.gdx.math.Vector3;
public class TouchUserInput extends UserInput {
public Vector3 userTouchEndPoint;
public TouchUserInput(){
this.userTouchEndPoint = new Vector3();
}
public TouchUserInput(Vector3 userTouchEndPoint){
this.userTouchEndPoint = new Vector3(userTouchEndPoint);
}
public TouchUserInput(float x, float y, float z){
this.userTouchEndPoint = new Vector3(x, y, z);
}
}

View File

@@ -1,21 +0,0 @@
/*
* 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.input;
/**
* Tag class for different user interaction wrapper classes.
*/
public abstract class UserInput{ }

View File

@@ -15,7 +15,7 @@
*/
package ve.ucv.ciens.ccg.nxtar.interfaces;
public interface ActionResolver{
public interface AndroidFunctionalityWrapper{
public void showShortToast(String msg);
public void showLongToast(String msg);
public void enableMulticast();

View File

@@ -16,23 +16,5 @@
package ve.ucv.ciens.ccg.nxtar.interfaces;
public interface ApplicationEventsListener {
/**
* <p>Callback used by the networking threads to notify sucessfull connections
* to the application</p>
*
* @param streamName The name of the thread notifying a connection.
*/
public void onNetworkStreamConnected(String streamName);
/**
* <p>Callback used by the assets loader to notify that all
* required game assets are ready to be used.</p>
*/
public void onAssetsLoaded();
/**
* <p>Callback used by the camera calibration state to notify that the
* camera has been succesfully calibrated.</p>
*/
public void onCameraCalibrated();
public void networkStreamConnected(String streamName);
}

View File

@@ -34,7 +34,6 @@ public class RobotControlThread extends Thread {
public static final String THREAD_NAME = "RobotControlThread";
private static final String TAG = "NXTAR_CORE_ROBOTTHREAD";
private static final String CLASS_NAME = RobotControlThread.class.getSimpleName();
private static int refCount = 0;
private ApplicationEventsListener netListener;
private ServerSocket server;
@@ -63,21 +62,13 @@ public class RobotControlThread extends Thread {
}
private static class SingletonHolder{
public static RobotControlThread INSTANCE;
public static final RobotControlThread INSTANCE = new RobotControlThread();
}
public static RobotControlThread getInstance(){
if(refCount == 0)
SingletonHolder.INSTANCE = new RobotControlThread();
refCount++;
return SingletonHolder.INSTANCE;
}
public static void freeInstance(){
refCount--;
if(refCount == 0) SingletonHolder.INSTANCE = null;
}
public void addNetworkConnectionListener(ApplicationEventsListener listener){
netListener = listener;
}
@@ -96,11 +87,6 @@ public class RobotControlThread extends Thread {
public void finish(){
done = true;
try{
server.close();
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error closing client: " + io.getMessage(), io);
}
}
@Override
@@ -111,7 +97,7 @@ public class RobotControlThread extends Thread {
try{
client = server.accept();
client.setTcpNoDelay(true);
if(netListener != null) netListener.onNetworkStreamConnected(THREAD_NAME);
if(netListener != null) netListener.networkStreamConnected(THREAD_NAME);
os = new ObjectOutputStream(client.getOutputStream());
is = new ObjectInputStream(client.getInputStream());
@@ -182,6 +168,7 @@ public class RobotControlThread extends Thread {
}
}
try{
client.close();
}catch(IOException io){

View File

@@ -29,7 +29,6 @@ public class SensorReportThread extends Thread {
public static final String THREAD_NAME = "SensorReportThread";
private static final String TAG = "NXTAR_CORE_ROBOTTHREAD";
private static final String CLASS_NAME = SensorReportThread.class.getSimpleName();
private static int refCount = 0;
private ApplicationEventsListener netListener;
private ServerSocket server;
@@ -57,21 +56,13 @@ public class SensorReportThread extends Thread {
}
private static class SingletonHolder{
public static SensorReportThread INSTANCE;
public final static SensorReportThread INSTANCE = new SensorReportThread();
}
public static SensorReportThread getInstance(){
if(refCount == 0)
SingletonHolder.INSTANCE = new SensorReportThread();
refCount++;
return SingletonHolder.INSTANCE;
}
public static void freeInstance(){
refCount--;
if(refCount == 0) SingletonHolder.INSTANCE = null;
}
public void addNetworkConnectionListener(ApplicationEventsListener listener){
netListener = listener;
}
@@ -90,11 +81,6 @@ public class SensorReportThread extends Thread {
public void finish(){
done = true;
try{
server.close();
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: IOException closing sockets: " + io.getMessage(), io);
}
}
public byte getLightSensorReading(){
@@ -114,7 +100,7 @@ public class SensorReportThread extends Thread {
try{
client = server.accept();
client.setTcpNoDelay(true);
if(netListener != null) netListener.onNetworkStreamConnected(THREAD_NAME);
if(netListener != null) netListener.networkStreamConnected(THREAD_NAME);
reader = client.getInputStream();
}catch(IOException io){
@@ -136,13 +122,5 @@ public class SensorReportThread extends Thread {
lightReading = reading[0];
}
}
try{
reader.close();
client.close();
server.close();
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: IOException closing sockets: " + io.getMessage(), io);
}
}
}

View File

@@ -38,28 +38,35 @@ import com.badlogic.gdx.Gdx;
* @author miky
*/
public class ServiceDiscoveryThread extends Thread {
public static final String THREAD_NAME = "ServiceDiscoveryThread";
/**
* The name used to identify this thread.
*/
public static final String THREAD_NAME = "ServiceDiscoveryThread";
/**
* Tag used for logging.
*/
private static final String TAG = "NXTAR_CORE_UDPTHREAD";
/**
* Class name used for logging.
*/
private static final String CLASS_NAME = ServiceDiscoveryThread.class.getSimpleName();
private static final int MAX_RETRIES = 5;
private static int refCount = 0;
/**
* Maximum number of transmission attempts before ending the thread abruptly.
*/
private static final int MAX_RETRIES = 5;
/**
* A semaphore object used to synchronize acces to this thread finish flag.
*/
private Object semaphore;
/**
* The finish flag.
*/
private boolean done;
/**
* The UDP server socket used for the ad hoc service discovery protocol.
*/
private DatagramSocket udpServer;
/**
* Holder for the multicast address used in the protocol.
*/
@@ -94,7 +101,7 @@ public class ServiceDiscoveryThread extends Thread {
* Singleton holder for this class.
*/
private static class SingletonHolder{
public static ServiceDiscoveryThread INSTANCE;
public static final ServiceDiscoveryThread INSTANCE = new ServiceDiscoveryThread();
}
/**
@@ -103,17 +110,9 @@ public class ServiceDiscoveryThread extends Thread {
* @return The singleton instance.
*/
public static ServiceDiscoveryThread getInstance(){
if(refCount == 0)
SingletonHolder.INSTANCE = new ServiceDiscoveryThread();
refCount++;
return SingletonHolder.INSTANCE;
}
public static void freeInstance(){
refCount--;
if(refCount == 0) SingletonHolder.INSTANCE = null;
}
/**
* This thread's run method.
*
@@ -139,7 +138,6 @@ public class ServiceDiscoveryThread extends Thread {
// Verify if the thread should end. If that is the case, close the server.
synchronized(semaphore){
if(done){
Gdx.app.log(TAG, CLASS_NAME + ".run(): Closing.");
udpServer.close();
break;
}

View File

@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
import ve.ucv.ciens.ccg.networkdata.VideoFrameDataMessage;
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
@@ -32,7 +33,6 @@ public class VideoStreamingThread extends Thread{
public static final String THREAD_NAME = "VideoStreamingThread";
private static final String TAG = "NXTAR_CORE_VIDEOTHREAD";
private static final String CLASS_NAME = VideoStreamingThread.class.getSimpleName();
private static int refCount = 0;
private ApplicationEventsListener netListener;
private DatagramSocket socket;
@@ -41,6 +41,7 @@ public class VideoStreamingThread extends Thread{
private boolean pause;
private boolean coreNotified;
private Object protocolPauseMonitor;
private Socket client;
private VideoFrameMonitor frameMonitor;
private long then;
private long now;
@@ -71,21 +72,13 @@ public class VideoStreamingThread extends Thread{
}
private static class SingletonHolder{
public static VideoStreamingThread INSTANCE;
public static final VideoStreamingThread INSTANCE = new VideoStreamingThread();
}
public static VideoStreamingThread getInstance(){
if(refCount == 0)
SingletonHolder.INSTANCE = new VideoStreamingThread();
refCount++;
return SingletonHolder.INSTANCE;
}
public static void freeInstance(){
refCount--;
if(refCount == 0) SingletonHolder.INSTANCE = null;
}
public void addNetworkConnectionListener(ApplicationEventsListener listener){
netListener = listener;
}
@@ -148,7 +141,6 @@ public class VideoStreamingThread extends Thread{
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message size from socket.");
try{
packet = new DatagramPacket(size, size.length);
socket.setSoTimeout(1000);
socket.receive(packet);
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException receiving size " + io.getMessage());
@@ -208,7 +200,7 @@ public class VideoStreamingThread extends Thread{
public int getFps(){
return fps;
}
public int getLostFrames(){
return lostFrames;
}
@@ -228,7 +220,7 @@ public class VideoStreamingThread extends Thread{
//Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Receiving.");
if(netListener != null && !coreNotified && frameMonitor.getCurrentFrame() != null){
coreNotified = true;
netListener.onNetworkStreamConnected(THREAD_NAME);
netListener.networkStreamConnected(THREAD_NAME);
}
receiveUdp();
frames++;
@@ -244,6 +236,12 @@ public class VideoStreamingThread extends Thread{
}
}
try{
client.close();
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error closing client socket.", io);
}
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Thread finished.");
}
@@ -252,7 +250,7 @@ public class VideoStreamingThread extends Thread{
pause = true;
}
}
public void play(){
synchronized (pauseMonitor){
pause = false;

View File

@@ -61,11 +61,14 @@ public class VideoFrameMonitor{
public void setNewFrame(byte[] frame){
byte[] temp;
Gdx.app.debug(TAG, CLASS_NAME + ".setNewFrame() :: Loading new frame in frameA.");
frameA = frame;
temp = frameA;
synchronized(frameMonitor){
Gdx.app.debug(TAG, CLASS_NAME + ".setNewFrame() :: Swapping frameA and frameB.");
frameA = frameB;
frameB = temp;
Gdx.app.debug(TAG, CLASS_NAME + ".setNewFrame() :: Swapping done.");
}
}
@@ -73,6 +76,7 @@ public class VideoFrameMonitor{
byte[] frame;
synchronized(frameMonitor){
//Gdx.app.debug(TAG, CLASS_NAME + ".getCurrentFrame() :: Fetching frameB.");
frame = frameB;
}
return frame;

View File

@@ -1,41 +0,0 @@
/*
* 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 ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
public abstract class AutomaticActionPerformerBase {
public enum automatic_action_t{
NO_ACTION,
GO_FORWARD,
GO_BACKWARDS,
STOP,
TURN_LEFT,
TURN_RIGHT,
BACKWARDS_LEFT,
BACKWARDS_RIGHT,
ROTATE_90,
RECENTER,
LOOK_RIGHT,
LOOK_LEFT,
STOP_LOOKING;
}
public abstract boolean performAutomaticAction(int lightSensorReading, MarkerData markers);
public abstract automatic_action_t getNextAction();
public abstract SummaryBase getSummary();
public abstract void reset();
}

View File

@@ -1,31 +0,0 @@
/*
* 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

@@ -1,249 +0,0 @@
/*
* 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 ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase;
import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.GameLogicSystemBase;
import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.RobotArmRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.PlayerSystemBase;
import ve.ucv.ciens.ccg.nxtar.systems.RobotArmPositioningSystem;
import com.artemis.EntitySystem;
import com.artemis.World;
import com.artemis.managers.GroupManager;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.utils.Disposable;
public abstract class ScenarioGlobals{
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 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)
throw new IllegalArgumentException("Core is null.");
if(modelBatch == null)
modelBatch = new ModelBatch();
if(gameWorld == null){
gameWorld = new World();
gameWorld.setManager(new GroupManager());
}
if(entityCreator == null){
try {
entityCreator = (EntityCreatorBase) ScenarioImplementation.entityCreatorClass.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating entity creator.");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing entity creator.");
throw e;
}
entityCreator.setWorld(gameWorld);
entityCreator.setCore(core);
}
if(gameLogicSystem == null){
try {
gameLogicSystem = (GameLogicSystemBase) ScenarioImplementation.gameLogicSystemClass.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating game logic system.");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing game logic system.");
throw e;
}
}
if(automaticActionPerformer == null){
try {
automaticActionPerformer = (AutomaticActionPerformerBase) ScenarioImplementation.automaticActionPerformerClass.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;
}
}
if(automaticActionSummaryOverlay == null){
try {
automaticActionSummaryOverlay = (SummaryOverlayBase) ScenarioImplementation.automaticActionSummaryOverlay.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating automatic action summary overlay");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing automatic action summary overlay.");
throw e;
}
}
if(playerSystem == null){
try {
playerSystem = (PlayerSystemBase) ScenarioImplementation.playerSystemClass.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating player system.");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing player system.");
throw e;
}
}
if(scenarioSummaryOverlay == null){
try {
scenarioSummaryOverlay = (SummaryOverlayBase) ScenarioImplementation.scenarioSummaryOverlayClass.newInstance();
} catch (InstantiationException e) {
System.out.println("Error instantiating scenario summary overlay.");
throw e;
} catch (IllegalAccessException e) {
System.out.println("Error accessing scenario summary overlay.");
throw e;
}
}
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());
gameWorld.setSystem(new RobotArmPositioningSystem());
gameWorld.setSystem(new GeometrySystem());
gameWorld.setSystem(new AnimationSystem());
gameWorld.setSystem(new CollisionDetectionSystem());
gameWorld.setSystem(gameLogicSystem);
gameWorld.setSystem(playerSystem, true);
gameWorld.setSystem(new MarkerRenderingSystem(modelBatch), true);
gameWorld.setSystem(new RobotArmRenderingSystem(modelBatch), true);
gameWorld.setSystem(new FadeEffectRenderingSystem(), true);
gameWorld.initialize();
}
public static void dispose() throws IllegalStateException{
ImmutableBag<EntitySystem> 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){
((Disposable)systems.get(i)).dispose();
}
}
scenarioSummaryOverlay.dispose();
automaticActionSummaryOverlay.dispose();
entityCreator.dispose();
hintsOverlay.dispose();
entityCreator = null;
gameLogicSystem = null;
gameWorld = null;
automaticActionPerformer = null;
automaticActionSummaryOverlay = null;
playerSystem = null;
scenarioSummaryOverlay = null;
hintsOverlay = null;
System.gc();
}
public static EntityCreatorBase getEntityCreator() throws IllegalStateException{
if(entityCreator == null)
throw new IllegalStateException("Calling getEntityCreator() before init.");
return entityCreator;
}
public static GameLogicSystemBase getGameLogicSystem() throws IllegalStateException{
if(gameLogicSystem == null)
throw new IllegalStateException("Calling getGameLogicSystem() before init.");
return gameLogicSystem;
}
public static World getGameWorld() throws IllegalStateException{
if(gameWorld == null)
throw new IllegalStateException("Calling getGameWorld() before init.");
return gameWorld;
}
public static AutomaticActionPerformerBase getAutomaticActionPerformer() throws IllegalStateException{
if(automaticActionPerformer == null)
throw new IllegalStateException("Calling getAutomaticActionPerformer() before init.");
return automaticActionPerformer;
}
public static SummaryOverlayBase getAutomaticActionSummaryOverlay() throws IllegalStateException{
if(automaticActionSummaryOverlay == null)
throw new IllegalStateException("Calling getAutomaticActionSummaryOverlay() before init.");
return automaticActionSummaryOverlay;
}
public static PlayerSystemBase getPlayerSystem() throws IllegalStateException{
if(playerSystem == null)
throw new IllegalStateException("Calling getPlayerSystem() before init.");
return playerSystem;
}
public static SummaryOverlayBase getScenarioSummaryOverlay() throws IllegalStateException{
if(scenarioSummaryOverlay == null)
throw new IllegalStateException("Calling getScenarioSummaryOverlay() before init.");
return scenarioSummaryOverlay;
}
public static HintsOverlayBase getHintsOverlay() throws IllegalStateException{
if(hintsOverlay == null)
throw new IllegalStateException("Calling getHintsOverlay() before init.");
return hintsOverlay;
}
}

View File

@@ -1,37 +0,0 @@
/*
* 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 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;
@SuppressWarnings("rawtypes")
public final class ScenarioImplementation{
public static final Class gameLogicSystemClass = BombGameLogicSystem.class;
public static final Class entityCreatorClass = BombGameEntityCreator.class;
public static final Class automaticActionPerformerClass = BombGameAutomaticActionPerformer.class;
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

@@ -1,31 +0,0 @@
/*
* 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 summary screens. Just renders a summary overlay.</p>
*/
public abstract class SummaryOverlayBase implements Disposable{
/**
* <p>Renders the overlay.</p>
*
* @param batch The {@link SpriteBatch} to use for rendering.
*/
public abstract void render(SpriteBatch batch, SummaryBase summary);
}

View File

@@ -1,50 +0,0 @@
/*
* 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 com.artemis.Component;
public class BombComponent extends Component {
public enum bomb_type_t{
COMBINATION(0), INCLINATION(1), WIRES(2);
private int value;
private bomb_type_t(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
};
public int id;
public bomb_type_t bombType;
public boolean enabled;
public BombComponent(int id, bomb_type_t bomb_type){
this.id = id;
this.bombType = bomb_type;
this.enabled = true;
}
public BombComponent(BombComponent bomb){
this.id = bomb.id;
this.bombType = bomb.bombType;
this.enabled = bomb.enabled;
}
}

View File

@@ -1,300 +0,0 @@
/*
* 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 java.util.LinkedList;
import java.util.List;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.scenarios.AutomaticActionPerformerBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.ScenarioGlobals;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryBase;
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 String TAG = "BOMB_GAME_AUTO_PERFORMER";
private static final String CLASS_NAME = BombGameAutomaticActionPerformer.class.getSimpleName();
private static final int MARKER_NEARBY_FLOOR_MIN_LUMINANCE = 50;
private enum action_state_t{
START, WALK_FORWARD, DETECT_MARKER, FINISHING, END;
}
public class BombGameAutomaticActionSummary extends SummaryBase{
private int numCombinationBombs;
private int numInclinationBombs;
private int numWireBombs;
private int totalBombs;
public BombGameAutomaticActionSummary(){
reset();
}
public int getNumCombinationBombs() {
return numCombinationBombs;
}
public int getNumInclinationBombs() {
return numInclinationBombs;
}
public int getNumWireBombs() {
return numWireBombs;
}
public void addCombinationBomb(){
numCombinationBombs++;
totalBombs++;
}
public void addInclinationBomb(){
numInclinationBombs++;
totalBombs++;
}
public void addWireBomb(){
numWireBombs++;
totalBombs++;
}
public int getBombsSeen(){
return totalBombs;
}
@Override
public void reset() {
this.numCombinationBombs = 0;
this.numInclinationBombs = 0;
this.numWireBombs = 0;
this.totalBombs = 0;
}
}
private automatic_action_t nextAction;
private action_state_t state;
private List<Integer> detectedMarkers;
private float then;
private float now;
private int stops;
private GroupManager manager;
private BombGameAutomaticActionSummary summary;
public BombGameAutomaticActionPerformer(){
nextAction = automatic_action_t.NO_ACTION;
state = action_state_t.START;
detectedMarkers = new LinkedList<Integer>();
then = 0.0f;
now = 0.0f;
manager = null;
summary = new BombGameAutomaticActionSummary();
}
@Override
public boolean performAutomaticAction(int lightSensorReading, MarkerData markers) throws IllegalStateException, IllegalArgumentException{
BombComponent bomb;
boolean finish = false;
boolean markerAlreadyDetected = false;
int detectedCode = -1;
ImmutableBag<Entity> entities = null;
float deltaT;
World world;
if(manager == null){
world = ScenarioGlobals.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.");
// Reset everything, then look to the left and start moving forward.
this.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.");
// Check if all stops have been found.
if(stops >= BombGameEntityCreator.NUM_BOMBS){
// If all stops have been found then stop the robot and finish the automatic action.
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Found goal.");
nextAction = automatic_action_t.STOP;
state = action_state_t.FINISHING;
}else{
// If there are stops to be found yet then check if the light sensor found a stop.
if(lightSensorReading >= MARKER_NEARBY_FLOOR_MIN_LUMINANCE){
// If a stop have been found then check if there is a marker nearby.
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{
// If the light sensor didn't find a stop the keep moving.
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Walking.");
nextAction = automatic_action_t.GO_FORWARD;
}
}
finish = false;
break;
case DETECT_MARKER:
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is DETECT_MARKER.");
for(int i = 0; !markerAlreadyDetected && 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){
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Marker already detected.");
markerAlreadyDetected = true;
break;
}
}
// If the marker has not been detected before then examine it.
if(!markerAlreadyDetected){
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): New marker detected.");
detectedCode = markers.markerCodes[i];
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 found a marker and it has not been detected before then add it to the detected markers list.
if(!markerAlreadyDetected && detectedCode != -1)
detectedMarkers.add(detectedCode);
if(lightSensorReading < MARKER_NEARBY_FLOOR_MIN_LUMINANCE){
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Switching to WALK_FORWARD.");
// If cleared the stop mark on the floor then start moving is search for the next mark.
state = action_state_t.WALK_FORWARD;
nextAction = automatic_action_t.STOP;
then = 0.0f;
now = 0.0f;
stops++;
}else{
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Clearing MARKER_NEARBY_FLOOR.");
// Wait for two seconds to make sure the marker can be correctly detected.
now += Gdx.graphics.getDeltaTime();
deltaT = now - then;
if(deltaT >= 2.0f){
nextAction = automatic_action_t.GO_FORWARD;
then = Gdx.graphics.getDeltaTime();
now = 0.0f;
}
}
finish = false;
break;
case FINISHING:
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is FINISHING.");
// Recenter the camera.
state = action_state_t.END;
nextAction = automatic_action_t.RECENTER;
finish = false;
break;
case END:
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is END.");
// Finish the automatic action.
nextAction = automatic_action_t.NO_ACTION;
state = action_state_t.START;
finish = true;
break;
default:
throw new IllegalStateException("Unknown automatic action state.");
}
return finish;
}
@Override
public automatic_action_t getNextAction() {
switch(nextAction){
default:
case NO_ACTION:
return automatic_action_t.NO_ACTION;
case GO_BACKWARDS:
return automatic_action_t.GO_BACKWARDS;
case GO_FORWARD:
return automatic_action_t.GO_FORWARD;
case STOP:
return automatic_action_t.STOP;
case ROTATE_90:
return automatic_action_t.ROTATE_90;
case RECENTER:
return automatic_action_t.RECENTER;
}
}
@Override
public SummaryBase getSummary() {
return (SummaryBase)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;
stops = 0;
}
}

View File

@@ -1,137 +0,0 @@
/*
* 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.SummaryBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryOverlayBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.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.controllers.mappings.Ouya;
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 SummaryOverlayBase{
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;
if(!Ouya.runningOnOuya)
fontParameters.size = (int)((float)ProjectConstants.MENU_BUTTON_FONT_SIZE * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH));
else
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);
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, SummaryBase 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);
font.draw(batch, "Bombs found: " + bombGameSummary.getBombsSeen(), wireX, inclinationY + inclinationBomb.getHeight() + font.getCapHeight() + 20.0f);
font.draw(batch, "Bombs expected: " + BombGameEntityCreator.NUM_BOMBS, wireX, inclinationY + inclinationBomb.getHeight() + 10.0f);
if(!Ouya.runningOnOuya)
titleFont.draw(batch, "Summary", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - titleHeight - 10);
else
titleFont.draw(batch, "Summary", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - 10);
}
}

View File

@@ -1,499 +0,0 @@
/*
* 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 java.util.LinkedList;
import java.util.List;
import ve.ucv.ciens.ccg.nxtar.components.AnimationComponent;
import ve.ucv.ciens.ccg.nxtar.components.AutomaticMovementComponent;
import ve.ucv.ciens.ccg.nxtar.components.CollisionDetectionComponent;
import ve.ucv.ciens.ccg.nxtar.components.CollisionModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.PlayerComponentBase;
import ve.ucv.ciens.ccg.nxtar.components.RenderModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.DirectionalLightPerPixelShader;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombComponent.bomb_type_t;
import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import com.artemis.Entity;
import com.artemis.managers.GroupManager;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.Shader;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.GdxRuntimeException;
public class BombGameEntityCreator extends EntityCreatorBase{
private static final String TAG = "BOMB_ENTITY_CREATOR";
private static final String CLASS_NAME = BombGameEntityCreator.class.getSimpleName();
private static final boolean DEBUG_RENDER_BOMB_COLLISION_MODELS = false;
private static final boolean DEBUG_RENDER_DOOR_COLLISION_MODELS = false;
private static final boolean DEBUG_RENDER_PARAPHERNALIA_COLLISION_MODELS = false;
public static final String DOORS_GROUP = "DOORS";
public static final Vector3 ROBOT_ARM_START_POINT = new Vector3(0.0f, 0.0f, -1.0f);
public static final int DOOR_OPEN_ANIMATION = 1;
public static final int DOOR_CLOSE_ANIMATION = 0;
public static int NUM_BOMBS = 0;
private class EntityParameters{
public Environment environment;
public Shader shader;
public int markerCode;
public int nextAnimation;
public boolean loopAnimation;
public EntityParameters(){
environment = new Environment();
shader = null;
markerCode = -1;
nextAnimation = -1;
loopAnimation = false;
}
}
private Shader shader;
private int currentBombId;
private GroupManager groupManager;
private List<Entity> entities;
private Entity player;
// Render models.
private Model robotArmModel = null;
private Model doorModel = null;
private Model doorFrameModel = null;
private Model combinationBombModel = null;
private Model combinationButton1Model = null;
private Model combinationButton2Model = null;
private Model combinationButton3Model = null;
private Model combinationButton4Model = null;
private Model inclinationBombModel = null;
private Model inclinationBombButtonModel = null;
private Model wiresBombModel = null;
private Model wiresBombModelWire1 = null;
private Model wiresBombModelWire2 = null;
private Model wiresBombModelWire3 = null;
private Model monkeyModel = null;
// Collision models.
private Model robotArmCollisionModel = null;
private Model doorCollisionModel = null;
private Model doorFrameCollisionModel = null;
private Model combinationBombCollisionModel = null;
private Model combinationButton1CollisionModel = null;
private Model combinationButton2CollisionModel = null;
private Model combinationButton3CollisionModel = null;
private Model combinationButton4CollisionModel = null;
private Model inclinationBombCollisionModel = null;
private Model inclinationBombButtonCollisionModel = null;
private Model wiresBombCollisionModel = null;
private Model wiresBombCollisionModelWire1 = null;
private Model wiresBombCollisionModelWire2 = null;
private Model wiresBombCollisionModelWire3 = null;
public BombGameEntityCreator(){
currentBombId = 0;
manager = new AssetManager();
entities = new LinkedList<Entity>();
player = null;
// Load the shader.
shader = new DirectionalLightPerPixelShader();
try{
shader.init();
}catch(GdxRuntimeException gdx){
Gdx.app.error(TAG, CLASS_NAME + ".BombGameEntityCreator(): Shader failed to load: " + gdx.getMessage());
shader = null;
}
// Load the render models.
manager.load("models/render_models/bomb_game/robot_arm.g3db", Model.class);
manager.load("models/render_models/bomb_game/door.g3db", Model.class);
manager.load("models/render_models/bomb_game/door_frame1.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_3_body.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_3_btn_1.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_3_btn_2.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_3_btn_3.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_3_btn_4.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_2_body.g3db", Model.class);
manager.load("models/render_models/bomb_game/big_btn.g3db", Model.class);
manager.load("models/render_models/bomb_game/bomb_1_body.g3db", Model.class);
manager.load("models/render_models/bomb_game/cable_1.g3db", Model.class);
manager.load("models/render_models/bomb_game/cable_2.g3db", Model.class);
manager.load("models/render_models/bomb_game/cable_3.g3db", Model.class);
manager.load("models/render_models/bomb_game/monkey.g3db", Model.class);
// Load the collision models.
manager.load("models/collision_models/bomb_game/robot_arm_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/door_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/door_frame1_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_3_body_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_3_btn_1_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_3_btn_2_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_3_btn_3_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_3_btn_4_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_2_body_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/big_btn_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/bomb_1_body_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/cable_1_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/cable_2_col.g3db", Model.class);
manager.load("models/collision_models/bomb_game/cable_3_col.g3db", Model.class);
}
@Override
public void createAllEntities(){
EntityParameters parameters;
Entity monkey;
groupManager = world.getManager(GroupManager.class);
// Create and set the lighting.
parameters = new EntityParameters();
parameters.environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 1.0f));
parameters.environment.add(new DirectionalLight().set(new Color(1, 1, 1, 1), new Vector3(0, 0, -1)));
parameters.shader = shader;
addRobotArm(parameters);
// Add bombs.
parameters.markerCode = 89;
addBomb(parameters, bomb_type_t.COMBINATION);
parameters.markerCode = 90;
addBomb(parameters, bomb_type_t.INCLINATION);
parameters.markerCode = 91;
addBomb(parameters, bomb_type_t.WIRES);
// Add doors.
parameters.nextAnimation = AnimationSystem.NO_ANIMATION;
parameters.loopAnimation = false;
parameters.markerCode = 89;
addDoor(parameters);
parameters.markerCode = 90;
addDoor(parameters);
parameters.markerCode = 91;
addDoor(parameters);
// Add the monkey.
monkey = world.createEntity();
monkey.addComponent(new RenderModelComponent(monkeyModel));
monkey.addComponent(new GeometryComponent());
monkey.addComponent(new MarkerCodeComponent(1023));
monkey.addComponent(new VisibilityComponent());
monkey.addComponent(new ShaderComponent(shader));
monkey.addComponent(new EnvironmentComponent(parameters.environment));
monkey.addToWorld();
entities.add(monkey);
// Create the player.
if(player == null){
player = world.createEntity();
player.addComponent(new BombGamePlayerComponent(3));
groupManager.add(player, PlayerComponentBase.PLAYER_GROUP);
player.addToWorld();
}else{
player.getComponent(BombGamePlayerComponent.class).reset();
}
entitiesCreated = true;
}
@Override
public boolean updateAssetManager() throws NullPointerException{
boolean doneLoading;
if(core == null)
throw new NullPointerException("Core has not been set.");
doneLoading = manager.update();
if(doneLoading){
getModels();
createAllEntities();
core.onAssetsLoaded();
}
return doneLoading;
}
@Override
public void dispose() {
if(shader != null) shader.dispose();
manager.dispose();
}
private void addRobotArm(EntityParameters parameters){
Entity robotArm = world.createEntity();
robotArm.addComponent(new GeometryComponent(new Vector3(ROBOT_ARM_START_POINT), new Matrix3(), new Vector3(1, 1, 1)));
robotArm.addComponent(new EnvironmentComponent(parameters.environment));
robotArm.addComponent(new ShaderComponent(parameters.shader));
robotArm.addComponent(new RenderModelComponent(robotArmModel));
robotArm.addComponent(new CollisionModelComponent(robotArmCollisionModel));
robotArm.addComponent(new CollisionDetectionComponent());
robotArm.addComponent(new AutomaticMovementComponent());
robotArm.addToWorld();
entities.add(robotArm);
}
private void addBomb(EntityParameters parameters, bomb_type_t type) throws IllegalArgumentException{
Entity bomb;
// Create a bomb entity and add it's generic components.
bomb = world.createEntity();
bomb.addComponent(new GeometryComponent(new Vector3(), new Matrix3(), new Vector3(1, 1, 1)));
bomb.addComponent(new EnvironmentComponent(parameters.environment));
bomb.addComponent(new ShaderComponent(parameters.shader));
bomb.addComponent(new MarkerCodeComponent(parameters.markerCode));
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);
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);
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);
if(DEBUG_RENDER_BOMB_COLLISION_MODELS)
addDebugCollisionModelRenderingEntity(wiresBombCollisionModel, parameters, false);
}else
throw new IllegalArgumentException("Unrecognized bomb type: " + Integer.toString(type.getValue()));
// 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){
Entity button1, button2, button3, button4;
button1 = addBombParaphernalia(combinationButton1Model, combinationButton1CollisionModel, parameters);
button2 = addBombParaphernalia(combinationButton2Model, combinationButton2CollisionModel, parameters);
button3 = addBombParaphernalia(combinationButton3Model, combinationButton3CollisionModel, parameters);
button4 = addBombParaphernalia(combinationButton4Model, combinationButton4CollisionModel, parameters);
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();
button3.addToWorld();
button4.addToWorld();
}
private void addBombInclinationButton(EntityParameters parameters){
Entity button;
button = addBombParaphernalia(inclinationBombButtonModel, inclinationBombButtonCollisionModel, parameters);
button.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.BIG_BUTTON));
button.addToWorld();
}
private void addBombWires(EntityParameters parameters){
Entity wire1, wire2, wire3;
wire1 = addBombParaphernalia(wiresBombModelWire1, wiresBombCollisionModelWire1, parameters);
wire2 = addBombParaphernalia(wiresBombModelWire2, wiresBombCollisionModelWire2, parameters);
wire3 = addBombParaphernalia(wiresBombModelWire3, wiresBombCollisionModelWire3, parameters);
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, EntityParameters parameters){
Entity thing;
thing = world.createEntity();
thing.addComponent(new GeometryComponent(new Vector3(), new Matrix3(), new Vector3(1, 1, 1)));
thing.addComponent(new EnvironmentComponent(parameters.environment));
thing.addComponent(new ShaderComponent(parameters.shader));
thing.addComponent(new RenderModelComponent(renderModel));
thing.addComponent(new CollisionModelComponent(collisionModel));
thing.addComponent(new VisibilityComponent());
thing.addComponent(new MarkerCodeComponent(parameters.markerCode));
thing.addComponent(new CollisionDetectionComponent());
groupManager.add(thing, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
groupManager.add(thing, Integer.toString(parameters.markerCode));
if(DEBUG_RENDER_PARAPHERNALIA_COLLISION_MODELS)
addDebugCollisionModelRenderingEntity(collisionModel, parameters, false);
entities.add(thing);
return thing;
}
private void addDoor(EntityParameters parameters){
ModelInstance doorInstance, doorColInstance;
Entity frame, door;
frame = world.createEntity();
frame.addComponent(new GeometryComponent(new Vector3(), new Matrix3(), new Vector3(1, 1, 1)));
frame.addComponent(new RenderModelComponent(doorFrameModel));
frame.addComponent(new CollisionModelComponent(doorFrameCollisionModel));
frame.addComponent(new CollisionDetectionComponent());
frame.addComponent(new EnvironmentComponent(parameters.environment));
frame.addComponent(new ShaderComponent(parameters.shader));
frame.addComponent(new VisibilityComponent());
frame.addComponent(new MarkerCodeComponent(parameters.markerCode));
frame.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.DOOR_FRAME));
groupManager.add(frame, Integer.toString(parameters.markerCode));
frame.addToWorld();
door = world.createEntity();
door.addComponent(new GeometryComponent(new Vector3(), new Matrix3(), new Vector3(1, 1, 1)));
door.addComponent(new RenderModelComponent(doorModel));
door.addComponent(new CollisionModelComponent(doorCollisionModel));
door.addComponent(new EnvironmentComponent(parameters.environment));
door.addComponent(new ShaderComponent(parameters.shader));
door.addComponent(new MarkerCodeComponent(parameters.markerCode));
door.addComponent(new VisibilityComponent());
doorInstance = door.getComponent(RenderModelComponent.class).instance;
doorColInstance = door.getComponent(CollisionModelComponent.class).instance;
door.addComponent(new AnimationComponent(doorInstance, parameters.nextAnimation, parameters.loopAnimation, doorColInstance));
door.addComponent(new CollisionDetectionComponent());
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);
door.addToWorld();
entities.add(frame);
entities.add(door);
if(DEBUG_RENDER_DOOR_COLLISION_MODELS){
addDebugCollisionModelRenderingEntity(doorFrameCollisionModel, parameters, false);
addDebugCollisionModelRenderingEntity(doorCollisionModel, parameters, true);
}
}
private void addDebugCollisionModelRenderingEntity(Model collisionModel, EntityParameters parameters, boolean animation){
ModelInstance instance;
Entity thing;
thing = world.createEntity();
thing.addComponent(new GeometryComponent(new Vector3(), new Matrix3(), new Vector3(1, 1, 1)));
thing.addComponent(new EnvironmentComponent(parameters.environment));
thing.addComponent(new ShaderComponent(parameters.shader));
thing.addComponent(new RenderModelComponent(collisionModel));
thing.addComponent(new VisibilityComponent());
thing.addComponent(new MarkerCodeComponent(parameters.markerCode));
if(animation){
instance = thing.getComponent(RenderModelComponent.class).instance;
thing.addComponent(new AnimationComponent(instance, parameters.nextAnimation, parameters.loopAnimation));
}
thing.addToWorld();
entities.add(thing);
}
private void getModels(){
// Get the render models.
robotArmModel = manager.get("models/render_models/bomb_game/robot_arm.g3db", Model.class);
doorModel = manager.get("models/render_models/bomb_game/door.g3db", Model.class);
doorFrameModel = manager.get("models/render_models/bomb_game/door_frame1.g3db", Model.class);
combinationBombModel = manager.get("models/render_models/bomb_game/bomb_3_body.g3db", Model.class);
combinationButton1Model = manager.get("models/render_models/bomb_game/bomb_3_btn_1.g3db", Model.class);
combinationButton2Model = manager.get("models/render_models/bomb_game/bomb_3_btn_2.g3db", Model.class);
combinationButton3Model = manager.get("models/render_models/bomb_game/bomb_3_btn_3.g3db", Model.class);
combinationButton4Model = manager.get("models/render_models/bomb_game/bomb_3_btn_4.g3db", Model.class);
inclinationBombModel = manager.get("models/render_models/bomb_game/bomb_2_body.g3db", Model.class);
inclinationBombButtonModel = manager.get("models/render_models/bomb_game/big_btn.g3db", Model.class);
wiresBombModel = manager.get("models/render_models/bomb_game/bomb_1_body.g3db", Model.class);
wiresBombModelWire1 = manager.get("models/render_models/bomb_game/cable_1.g3db", Model.class);
wiresBombModelWire2 = manager.get("models/render_models/bomb_game/cable_2.g3db", Model.class);
wiresBombModelWire3 = manager.get("models/render_models/bomb_game/cable_3.g3db", Model.class);
monkeyModel = manager.get("models/render_models/bomb_game/monkey.g3db", Model.class);
// Get the collision models.
robotArmCollisionModel = manager.get("models/collision_models/bomb_game/robot_arm_col.g3db", Model.class);
doorCollisionModel = manager.get("models/collision_models/bomb_game/door_col.g3db", Model.class);
doorFrameCollisionModel = manager.get("models/collision_models/bomb_game/door_frame1_col.g3db", Model.class);
combinationBombCollisionModel = manager.get("models/collision_models/bomb_game/bomb_3_body_col.g3db", Model.class);
combinationButton1CollisionModel = manager.get("models/collision_models/bomb_game/bomb_3_btn_1_col.g3db", Model.class);
combinationButton2CollisionModel = manager.get("models/collision_models/bomb_game/bomb_3_btn_2_col.g3db", Model.class);
combinationButton3CollisionModel = manager.get("models/collision_models/bomb_game/bomb_3_btn_3_col.g3db", Model.class);
combinationButton4CollisionModel = manager.get("models/collision_models/bomb_game/bomb_3_btn_4_col.g3db", Model.class);
inclinationBombCollisionModel = manager.get("models/collision_models/bomb_game/bomb_2_body_col.g3db", Model.class);
inclinationBombButtonCollisionModel = manager.get("models/collision_models/bomb_game/big_btn_col.g3db", Model.class);
wiresBombCollisionModel = manager.get("models/collision_models/bomb_game/bomb_1_body_col.g3db", Model.class);
wiresBombCollisionModelWire1 = manager.get("models/collision_models/bomb_game/cable_1_col.g3db", Model.class);
wiresBombCollisionModelWire2 = manager.get("models/collision_models/bomb_game/cable_2_col.g3db", Model.class);
wiresBombCollisionModelWire3 = manager.get("models/collision_models/bomb_game/cable_3_col.g3db", Model.class);
}
@Override
public void resetAllEntities() {
for(Entity entity : entities){
try{
if(entity.isActive())
entity.deleteFromWorld();
}catch(NullPointerException n){
Gdx.app.error(TAG, CLASS_NAME + ".resetAllEntities(): Null pointer exception while deleting entity.");
}
}
entities.clear();
NUM_BOMBS = 0;
createAllEntities();
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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 com.artemis.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;
public static final int BIG_BUTTON = 20;
public static final int COM_BUTTON_1 = 30;
public static final int COM_BUTTON_2 = 31;
public static final int COM_BUTTON_3 = 32;
public static final int COM_BUTTON_4 = 33;
public static final int DOOR = 40;
public static final int DOOR_FRAME = 41;
public static final int FADE_EFFECT = 90;
public int type;
public BombGameEntityTypeComponent(int type){
this.type = type;
}
}

View File

@@ -1,127 +0,0 @@
/*
* 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.controllers.mappings.Ouya;
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;
if(!Ouya.runningOnOuya)
fontParameters.size = (int)((float)ProjectConstants.MENU_BUTTON_FONT_SIZE * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH));
else
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);
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);
if(!Ouya.runningOnOuya)
titleFont.draw(batch, "Instructions", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - titleHeight - 10);
else
titleFont.draw(batch, "Instructions", -(titleWidth / 2), (Utils.getScreenHeightWithOverscan() / 2) - 10);
}
}

View File

@@ -1,511 +0,0 @@
/*
* 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.components.AnimationComponent;
import ve.ucv.ciens.ccg.nxtar.components.CollisionDetectionComponent;
import ve.ucv.ciens.ccg.nxtar.components.FadeEffectComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.PlayerComponentBase;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.GameLogicSystemBase;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.World;
import com.artemis.annotations.Mapper;
import com.artemis.managers.GroupManager;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.Gdx;
public class BombGameLogicSystem extends GameLogicSystemBase {
private static final String TAG = "BOMB_GAME_LOGIC";
private static final String CLASS_NAME = BombGameLogicSystem.class.getSimpleName();
private enum combination_button_state_t{
CORRECT(0), INCORRECT(1), DISABLED(2);
private int value;
private combination_button_state_t(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
@Mapper ComponentMapper<BombGameEntityTypeComponent> typeMapper;
@Mapper ComponentMapper<AnimationComponent> animationMapper;
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<CollisionDetectionComponent> collisionMapper;
@Mapper ComponentMapper<FadeEffectComponent> fadeMapper;
private MarkerCodeComponent tempMarker;
private BombGameEntityTypeComponent tempType;
private GroupManager manager;
private int then;
@SuppressWarnings("unchecked")
public BombGameLogicSystem(){
super(Aspect.getAspectForAll(BombGameEntityTypeComponent.class));
manager = null;
then = 0;
}
@Override
protected void process(Entity e){
BombGameEntityTypeComponent typeComponent;
if(manager == null)
manager = world.getManager(GroupManager.class);
typeComponent = typeMapper.get(e);
switch(typeComponent.type){
case BombGameEntityTypeComponent.BOMB_WIRE_1:
case BombGameEntityTypeComponent.BOMB_WIRE_2:
case BombGameEntityTypeComponent.BOMB_WIRE_3:
processWireBomb(e);
break;
case BombGameEntityTypeComponent.BIG_BUTTON:
processInclinationBomb(e);
break;
case BombGameEntityTypeComponent.COM_BUTTON_1:
case BombGameEntityTypeComponent.COM_BUTTON_2:
case BombGameEntityTypeComponent.COM_BUTTON_3:
case BombGameEntityTypeComponent.COM_BUTTON_4:
processCombinationBomb(e);
break;
case BombGameEntityTypeComponent.DOOR:
processDoor(e);
break;
case BombGameEntityTypeComponent.FADE_EFFECT:
processFade(e);
break;
default:
break;
}
}
/**
* <p>Checks if the current player interaction disables a wire based bomb.</p>
*
* @param b An Artemis {@link Entity} that possibly represents any of a Wire Bomb's wires.
*/
private void processWireBomb(Entity b){
CollisionDetectionComponent collision;
MarkerCodeComponent marker;
BombGameEntityTypeComponent wireType;
// Get this wire's parameters.
collision = collisionMapper.getSafe(b);
marker = markerMapper.getSafe(b);
wireType = typeMapper.getSafe(b);
// if any of the parameters is missing then skip.
if(marker == null || collision == null || wireType == null){
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Wire bomb is missing some components.");
return;
}
// If this bomb is still enabled and it's door is already open then process it.
try{
if(marker.enabled && isDoorOpen(marker.code, manager) && collision.colliding){
manager.remove(b, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
manager.remove(b, Integer.toString(marker.code));
b.deleteFromWorld();
if(wireType.type != BombGameEntityTypeComponent.BOMB_WIRE_1){
Gdx.app.log(TAG, CLASS_NAME + ".processWireBomb(): Wire bomb exploded.");
createFadeOutEffect();
reducePlayerLivesByOne();
}
disableBomb(marker.code);
Gdx.app.log(TAG, CLASS_NAME + ".processWireBomb(): Wire bomb disabled.");
}
}catch(IllegalArgumentException e){
Gdx.app.error(TAG, CLASS_NAME + ".processWireBomb(): IllegalArgumentException caught: " + e.getMessage());
}
}
/**
* <p>Checks if the current player interaction disables a combination bomb.</p>
*
* @param b An Artemis {@link Entity} that possibly represents any of a Combination Bomb's buttons.
*/
private void processCombinationBomb(Entity b){
combination_button_state_t state;
CollisionDetectionComponent collision;
MarkerCodeComponent marker;
BombGameEntityTypeComponent buttonType;
// Get this wire's parameters.
collision = collisionMapper.getSafe(b);
marker = markerMapper.getSafe(b);
buttonType = typeMapper.getSafe(b);
// if any of the parameters is missing then skip.
if(marker == null || collision == null || buttonType == null){
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Wire bomb is missing some components.");
return;
}
// If this bomb is still enabled and it's door is already open then process it.
try{
if(marker.enabled && isDoorOpen(marker.code, manager) && collision.colliding){
manager.remove(b, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
manager.remove(b, Integer.toString(marker.code));
b.deleteFromWorld();
// Check the state of the other buttons associated with this bomb.
state = checkCombinationBombButtons(buttonType.type, marker.code);
if(state.getValue() == combination_button_state_t.INCORRECT.getValue()){
Gdx.app.log(TAG, CLASS_NAME + ".processCombinationBomb(): Combination bomb exploded.");
createFadeOutEffect();
disableBomb(marker.code);
reducePlayerLivesByOne();
}else if(state.getValue() == combination_button_state_t.DISABLED.getValue()){
Gdx.app.log(TAG, CLASS_NAME + ".processCombinationBomb(): Combination bomb disabled.");
disableBomb(marker.code);
}
}
}catch(IllegalArgumentException e){
Gdx.app.error(TAG, CLASS_NAME + ".processCombinationBomb(): IllegalArgumentException caught: " + e.getMessage());
}
}
/**
* <p>Checks if the current player interaction disables an inclination bomb.</p>
*
* @param b An Artemis {@link Entity} that possibly represents an Inclination Bomb's big button.
*/
private void processInclinationBomb(Entity b){
// Get the components of the big button.
CollisionDetectionComponent collision = collisionMapper.getSafe(b);
MarkerCodeComponent marker = markerMapper.getSafe(b);
// If any of the components is missing, skip this entity.
if(marker == null || collision == null ){
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Inclination bomb is missing some components.");
return;
}
// If this bomb is still enabled and it's door is already open then process it.
try{
if(marker.enabled && isDoorOpen(marker.code, manager) && collision.colliding){
// Disable the bomb and remove it from collision detection.
marker.enabled = false;
manager.remove(b, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
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);
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Inclination bomb disabled.");
}
}catch(IllegalArgumentException e){
Gdx.app.error(TAG, CLASS_NAME + ".processInclinationBomb(): IllegalArgumentException caught: " + e.getMessage());
}
}
/**
* <p>Set's the animation for a door depending on it's collision and marker state.</p>
*
* @param d An Artemis {@link Entity} possibly representing a door.
*/
private void processDoor(Entity d){
// Get the components of the door.
CollisionDetectionComponent collision = collisionMapper.getSafe(d);
AnimationComponent animation = animationMapper.getSafe(d);
VisibilityComponent visibility = visibilityMapper.getSafe(d);
MarkerCodeComponent marker = markerMapper.getSafe(d);
// If any of the components is missing, skip this entity.
if(marker == null || collision == null || animation == null || visibility == null){
Gdx.app.log(TAG, CLASS_NAME + ".processDoor(): Door is missing some components.");
return;
}
if(visibility.visible){
if(marker.enabled){
if(collision.colliding){
// If the door is visible and enabled and the player is colliding with it then set
// it's opening animation;
animation.next = BombGameEntityCreator.DOOR_OPEN_ANIMATION;
animation.loop = false;
collision.colliding = false;
world.getManager(GroupManager.class).remove(d, CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
Gdx.app.log(TAG, CLASS_NAME + ".processDoor(): Opening door.");
}
}else{
// If the door is disabled and open, then set it's closing animation.
if(animation.current != BombGameEntityCreator.DOOR_CLOSE_ANIMATION){
animation.next = BombGameEntityCreator.DOOR_CLOSE_ANIMATION;
animation.loop = false;
Gdx.app.log(TAG, CLASS_NAME + ".processDoor(): Closing door.");
}
}
}
}
/**
* <p>Checks if a door is either open or closed depending on the completeness of it's animation.</p>
*
* @param markerCode The code of the door to check. Must be between 0 and 1023.
* @param manager An Artemis {@link GroupManager} to use to get all related entities.
* @return true if the opening animation of the door has finished playing.
* @throws IllegalArgumentException If marker code is not in the range [0, 1023], inclusive.
*/
private boolean isDoorOpen(int markerCode, GroupManager manager) throws IllegalArgumentException{
AnimationComponent animation;
boolean doorOpen = false;
ImmutableBag<Entity> doors = manager.getEntities(BombGameEntityCreator.DOORS_GROUP);
if(markerCode < 0 || markerCode > 1023)
throw new IllegalArgumentException("Marker code is not within range [0, 1023]: " + Integer.toString(markerCode));
// For every door.
for(int i = 0; i < doors.size(); i++){
tempMarker = markerMapper.getSafe(doors.get(i));
animation = animationMapper.getSafe(doors.get(i));
if(animation == null || tempMarker == null) return false;
// If this is the door we are looking for and it's opening animation is finished then this door is open.
if(tempMarker.code == markerCode && animation.current == BombGameEntityCreator.DOOR_OPEN_ANIMATION && animation.controller.current.loopCount == 0){
doorOpen = true;
break;
}
}
return doorOpen;
}
/**
* <p>Updates the player's lives count.</p>
*/
private void reducePlayerLivesByOne(){
Entity player;
BombGamePlayerComponent playerComponent;
ImmutableBag<Entity> players;
players = manager.getEntities(PlayerComponentBase.PLAYER_GROUP);
if(players != null && players.size() > 0 && players.get(0) != null){
player = players.get(0);
playerComponent = player.getComponent(BombGamePlayerComponent.class);
if(playerComponent != null){
playerComponent.lives -= 1;
}else{
Gdx.app.log(TAG, CLASS_NAME + ".reducePlayerLivesByOne(): Players is missing required components.");
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".reducePlayerLivesByOne(): No players found.");
}
}
/**
* <p>Updates the player's disabled bombs count.</p>
*/
private void increasePlayerDisabledBombsByOne(){
Entity player;
BombGamePlayerComponent playerComponent;
ImmutableBag<Entity> players;
players = manager.getEntities(PlayerComponentBase.PLAYER_GROUP);
if(players != null && players.size() > 0 && players.get(0) != null){
player = players.get(0);
playerComponent = player.getComponent(BombGamePlayerComponent.class);
if(playerComponent != null){
playerComponent.disabledBombs += 1;
}else{
Gdx.app.log(TAG, CLASS_NAME + ".reducePlayerLivesByOne(): Players is missing required components.");
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".reducePlayerLivesByOne(): No players found.");
}
}
/**
* <p>Disables all entities associated with the corresponding marker code.</p>
*
* @param markerCode
* @throws IllegalArgumentException If marker code is not in the range [0, 1023], inclusive.
*/
private void disableBomb(int markerCode) throws IllegalArgumentException{
ImmutableBag<Entity> related = manager.getEntities(Integer.toString(markerCode));
if(markerCode < 0 || markerCode > 1023)
throw new IllegalArgumentException("Marker code is not within range [0, 1023]: " + Integer.toString(markerCode));
// Disable every entity sharing this marker code except for the corresponding door frame.
for(int i = 0; i < related.size(); i++){
tempMarker = markerMapper.getSafe(related.get(i));
tempType = typeMapper.getSafe(related.get(i));
// 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 != 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 != BombGameEntityTypeComponent.DOOR_FRAME){
manager.add(related.get(i), CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
}
}
}
increasePlayerDisabledBombsByOne();
}
/**
* <p>Checks if a combination bomb is being disabled in the correct sequence.</p>
*
* @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.
*/
private combination_button_state_t checkCombinationBombButtons(int buttonType, int markerCode) throws IllegalArgumentException{
combination_button_state_t state;
boolean correctSequence = true;
int remainingButtons = 0;
ImmutableBag<Entity> related;
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)
throw new IllegalArgumentException("Marker code is not within range [0, 1023]: " + Integer.toString(markerCode));
related = manager.getEntities(Integer.toString(markerCode));
// Check the state of the other buttons associated with this bomb.
for(int i = 0; i < related.size(); i++){
tempType = typeMapper.getSafe(related.get(i));
if(tempType == null) continue;
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++;
continue;
}else{
// If this remaining button is an incorrect one then the sequence is wrong.
correctSequence = false;
break;
}
}else continue;
}
if(!correctSequence)
state = combination_button_state_t.INCORRECT;
else
if(remainingButtons == 0)
state = combination_button_state_t.DISABLED;
else
state = combination_button_state_t.CORRECT;
return state;
}
/**
* <p>Adds a new fade out entity to the {@link World}.</p>
*/
private void createFadeOutEffect(){
Entity effect = world.createEntity();
effect.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.FADE_EFFECT));
effect.addComponent(new FadeEffectComponent());
effect.addToWorld();
}
/**
* <p>Adds a new fade in entity to the {@link World}.</p>
*/
private void createFadeInEffect(){
Entity effect = world.createEntity();
effect.addComponent(new BombGameEntityTypeComponent(BombGameEntityTypeComponent.FADE_EFFECT));
effect.addComponent(new FadeEffectComponent(true));
effect.addToWorld();
}
/**
* <p>Updates a fade effect entity.</p>
*
* @param f An Artemis {@link Entity} possibly referencing a fade effect.
*/
private void processFade(Entity f){
FadeEffectComponent fade = fadeMapper.getSafe(f);
if(fade != null){
if(!fade.isEffectStarted())
fade.startEffect();
if(!fade.isEffectFinished()){
// If the fade has not finished then just update it.
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Updating fade.");
fade.update(Gdx.graphics.getDeltaTime());
}else{
// If the fade finished.
if(fade.isEffectFadeIn()){
// If the effect was a fade in then just remove it.
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): deleting fade in.");
f.deleteFromWorld();
}else{
// If the effect was a fade out then wait for one second and then remove it and start a fade in.
then += (int)(Gdx.graphics.getDeltaTime() * 1000.0f);
if(then >= 1500){
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Deleting fade out.");
f.deleteFromWorld();
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Creating fade in.");
createFadeInEffect();
then = 0;
}else{
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Waiting after fade out: " + Integer.toString(then));
}
}
}
}
}
}

View File

@@ -1,49 +0,0 @@
/*
* 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.components.PlayerComponentBase;
public class BombGamePlayerComponent extends PlayerComponentBase {
public static final int MIN_LIVES = 1;
public static final int MAX_LIVES = 5;
public int startingLives;
public int lives;
public int disabledBombs;
public BombGamePlayerComponent(int lives) throws IllegalArgumentException{
super();
if(lives < MIN_LIVES || lives > MAX_LIVES)
throw new IllegalArgumentException("Lives number out of range: " + Integer.toString(lives));
startingLives = lives;
reset();
}
public BombGamePlayerComponent(){
this(3);
}
@Override
public void reset(){
super.reset();
this.lives = startingLives;
this.disabledBombs = 0;
}
}

View File

@@ -1,118 +0,0 @@
/*
* 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.scenarios.bombgame;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryBase;
import ve.ucv.ciens.ccg.nxtar.systems.PlayerSystemBase;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class BombGamePlayerSystem extends PlayerSystemBase{
public final class BombGamePlayerSummary extends SummaryBase{
public int livesLeft;
public int disabledBombs;
public int detonatedBombs;
public boolean victory;
public BombGamePlayerSummary(){
reset();
}
@Override
public void reset() {
this.livesLeft = 0;
this.disabledBombs = 0;
this.detonatedBombs = 0;
this.victory = false;
}
}
@Mapper ComponentMapper<BombGamePlayerComponent> playerMapper;
private SpriteBatch batch;
private Texture heartTexture;
private Sprite heart;
private OrthographicCamera camera;
private BombGamePlayerSummary summary;
private float heartYPos;
public BombGamePlayerSystem(){
super(BombGamePlayerComponent.class);
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch = new SpriteBatch();
heartTexture = new Texture(Gdx.files.internal("data/gfx/bomb_game/Anonymous_heart_1.png"));
summary = new BombGamePlayerSummary();
heart = new Sprite(heartTexture);
heart.setSize(heart.getWidth() * 0.25f, heart.getHeight() * 0.25f);
heartYPos = (Utils.getScreenHeightWithOverscan() / 2) - heart.getHeight() - 64 - 5;
}
@Override
protected void process(Entity e){
float heartXPos;
BombGamePlayerComponent player = playerMapper.get(e);
// Render remaining lives.
batch.setProjectionMatrix(camera.combined);
batch.begin();{
heartXPos = -(Utils.getScreenWidthWithOverscan() / 2) + 5;
for(int i = 0; i < player.lives; ++i){
heart.setPosition(heartXPos, heartYPos);
heart.draw(batch);
heartXPos += heart.getWidth() + 5;
}
}batch.end();
// Check ending conditions.
if(player.lives <= 0){
player.gameFinished = true;
player.victory = false;
}else if(player.disabledBombs >= BombGameEntityCreator.NUM_BOMBS){
player.gameFinished = true;
player.victory = true;
}
if(player.gameFinished){
summary.victory = player.victory;
summary.livesLeft = player.lives;
summary.disabledBombs = BombGameEntityCreator.NUM_BOMBS - (player.startingLives - player.lives);
summary.detonatedBombs = player.startingLives - player.lives;
finishGame(player.victory);
}
}
@Override
public void dispose() {
if(batch != null)
batch.dispose();
if(heartTexture != null)
heartTexture.dispose();
}
@Override
public SummaryBase getPlayerSummary() {
return summary;
}
}

View File

@@ -1,109 +0,0 @@
/*
* 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.SummaryBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryOverlayBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.bombgame.BombGamePlayerSystem.BombGamePlayerSummary;
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.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
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 BombGameScenarioEndingOverlay extends SummaryOverlayBase {
private static final float CANNONICAL_SCREEN_WIDTH = 800.0f;
private BitmapFont font;
private BitmapFont titleFont;
private float textX;
private float baseTextY;
private TextBounds titleBounds;
public BombGameScenarioEndingOverlay(){
FreeTypeFontGenerator fontGenerator;
FreeTypeFontParameter fontParameters;
fontParameters = new FreeTypeFontParameter();
fontParameters.characters = ProjectConstants.FONT_CHARS;
if(!Ouya.runningOnOuya)
fontParameters.size = (int)(65.0f * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH));
else
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);
font.setColor(Color.YELLOW);
fontParameters.size = (int)(90.0f * ((float)Gdx.graphics.getWidth() / CANNONICAL_SCREEN_WIDTH));
titleFont = fontGenerator.generateFont(fontParameters);
fontGenerator.dispose();
textX = -(Utils.getScreenWidthWithOverscan() / 7.0f);
baseTextY = -(font.getCapHeight() / 2.0f);
}
@Override
public void dispose(){
font.dispose();
titleFont.dispose();
}
@Override
public void render(SpriteBatch batch, SummaryBase summary) throws ClassCastException{
BombGamePlayerSummary bombGamePlayerSummary;
String title;
String text;
// Get the player's summary.
if(!(summary instanceof BombGamePlayerSummary))
throw new ClassCastException("Summary is not a bomb game summary.");
bombGamePlayerSummary = (BombGamePlayerSummary)summary;
// Render the summary.
text = String.format("Lives left: %d", bombGamePlayerSummary.livesLeft);
textX = -(font.getBounds(text).width / 2);
font.draw(batch, text, textX, baseTextY + font.getCapHeight() + 15);
text = String.format("Bombs defused: %d", bombGamePlayerSummary.disabledBombs);
textX = -(font.getBounds(text).width / 2);
font.draw(batch, text, textX, baseTextY);
text = String.format("Bombs detonated: %d", bombGamePlayerSummary.detonatedBombs);
textX = -(font.getBounds(text).width / 2);
font.draw(batch, text, textX, baseTextY - font.getCapHeight() - 15);
// Render the title.
if(bombGamePlayerSummary.victory)
title = "Victory!";
else
title = "Game Over";
titleBounds = titleFont.getBounds(title);
if(!Ouya.runningOnOuya)
titleFont.draw(batch, title, -(titleBounds.width / 2), (Utils.getScreenHeightWithOverscan() / 2) - titleBounds.height - 10);
else
titleFont.draw(batch, title, -(titleBounds.width / 2), (Utils.getScreenHeightWithOverscan() / 2) - 10);
}
}

View File

@@ -1,699 +0,0 @@
/*
* 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.networkdata.MotorEvent;
import ve.ucv.ciens.ccg.networkdata.MotorEvent.motor_t;
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
import ve.ucv.ciens.ccg.nxtar.graphics.CustomPerspectiveCamera;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread;
import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue;
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
import ve.ucv.ciens.ccg.nxtar.scenarios.AutomaticActionPerformerBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.ScenarioGlobals;
import ve.ucv.ciens.ccg.nxtar.scenarios.AutomaticActionPerformerBase.automatic_action_t;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.World;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.Sprite;
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.g3d.ModelBatch;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
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 AutomaticActionState extends BaseState{
private static final String TAG = "AUTOMATIC_STATE";
private static final String CLASS_NAME = AutomaticActionState.class.getSimpleName();
private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg";
private static final float NEAR = 0.01f;
private static final float FAR = 100.0f;
// Background related fields.
private Sprite background;
private float uScaling[];
private Texture backgroundTexture;
private ShaderProgram backgroundShader;
// 3D rendering fields.
private ModelBatch modelBatch;
private FrameBuffer frameBuffer;
private Sprite frameBufferSprite;
// Game related fields.
private World gameWorld;
private MarkerRenderingSystem markerRenderingSystem;
private boolean ignoreBackKey;
private boolean automaticActionEnabled;
private AutomaticActionPerformerBase automaticActionPerformer;
private automatic_action_t previousAction;
// Cameras.
private OrthographicCamera unitaryOrthographicCamera;
private OrthographicCamera pixelPerfectOrthographicCamera;
private CustomPerspectiveCamera perspectiveCamera;
// Video stream graphics.
private Texture videoFrameTexture;
private Sprite renderableVideoFrame;
private Pixmap videoFrame;
// Gui elements.
private Texture startButtonEnabledTexture;
private Texture startButtonDisabledTexture;
private Texture startButtonPressedTexture;
private NinePatch startButtonEnabled9p;
private NinePatch startButtonDisabled9p;
private NinePatch startButtonPressed9p;
private BitmapFont font;
private TextButton startButton;
private Rectangle startButtonBBox;
private boolean startButtonPressed;
private Texture ouyaOButtonTexture;
private Sprite ouyaOButton;
private boolean oButtonPressed;
private boolean aButtonPressed;
// Button touch helper fields.
private boolean[] buttonsTouched;
private int[] buttonPointers;
private boolean[] gamepadButtonPressed;
// Monitors.
private VideoFrameMonitor frameMonitor;
private MotorEventQueue queue;
private SensorReportThread sensorThread;
public AutomaticActionState(final NxtARCore core) throws IllegalStateException, IllegalArgumentException{
if(core == null)
throw new IllegalArgumentException(CLASS_NAME + ": Core is null.");
this.core = core;
frameMonitor = VideoFrameMonitor.getInstance();
queue = MotorEventQueue.getInstance();
sensorThread = SensorReportThread.getInstance();
ignoreBackKey = false;
videoFrame = null;
aButtonPressed = false;
automaticActionEnabled = false;
startButtonPressed = false;
automaticActionPerformer = ScenarioGlobals.getAutomaticActionPerformer();
previousAction = automatic_action_t.NO_ACTION;
// Set up the cameras.
pixelPerfectOrthographicCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
unitaryOrthographicCamera = new OrthographicCamera(1.0f, Gdx.graphics.getHeight() / Gdx.graphics.getWidth());
// Set up input handling support fields.
win2world = new Vector3(0.0f, 0.0f, 0.0f);
touchPointWorldCoords = new Vector2();
buttonsTouched = new boolean[1];
buttonsTouched[0] = false;
buttonPointers = new int[1];
buttonPointers[0] = -1;
gamepadButtonPressed = new boolean[1];
gamepadButtonPressed[0] = false;
// Set up the background.
backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png"));
backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
background = new Sprite(backgroundTexture);
background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
// Set up the shader.
backgroundShader = new ShaderProgram(Gdx.files.internal(BACKGROUND_SHADER_PATH + "_vert.glsl"), Gdx.files.internal(BACKGROUND_SHADER_PATH + "_frag.glsl"));
if(!backgroundShader.isCompiled()){
Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the background shader.");
Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog());
backgroundShader = null;
}
uScaling = new float[2];
uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f;
uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f;
// Set up the 3D rendering.
modelBatch = new ModelBatch();
frameBuffer = null;
perspectiveCamera = null;
frameBufferSprite = null;
// Create the gui.
setUpButton();
// Set up the game world.
gameWorld = ScenarioGlobals.getGameWorld();
markerRenderingSystem = gameWorld.getSystem(MarkerRenderingSystem.class);
if(markerRenderingSystem == null)
throw new IllegalStateException(CLASS_NAME + ": Essential marker rendering system is null.");
}
/*;;;;;;;;;;;;;;;;;;;;;;
; BASE STATE METHODS ;
;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public void render(float delta){
int w, h;
byte[] frame;
MarkerData data;
TextureRegion region;
float focalPointX, focalPointY, cameraCenterX, cameraCenterY;
// Clear the screen.
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// Render the background.
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
core.batch.begin();{
if(backgroundShader != null){
core.batch.setShader(backgroundShader);
backgroundShader.setUniform2fv("u_scaling", uScaling, 0, 2);
}
background.draw(core.batch);
if(backgroundShader != null) core.batch.setShader(null);
}core.batch.end();
// Fetch the current video frame.
frame = frameMonitor.getCurrentFrame();
w = frameMonitor.getFrameDimensions().getWidth();
h = frameMonitor.getFrameDimensions().getHeight();
// Create the 3D perspective camera and the frame buffer object if they don't exist.
if(perspectiveCamera == null && frameBuffer == null){
frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
perspectiveCamera = new CustomPerspectiveCamera(67, w, h);
perspectiveCamera.translate(0.0f, 0.0f, 0.0f);
perspectiveCamera.near = NEAR;
perspectiveCamera.far = FAR;
perspectiveCamera.lookAt(0.0f, 0.0f, -1.0f);
perspectiveCamera.update();
}
// Attempt to find the markers in the current video frame.
data = core.cvProc.findMarkersInFrame(frame);
// If a valid frame was fetched.
if(data != null && data.outFrame != null){
if(automaticActionEnabled)
performAutomaticAction(data);
// Set the camera to the correct projection.
focalPointX = core.cvProc.getFocalPointX();
focalPointY = core.cvProc.getFocalPointY();
cameraCenterX = core.cvProc.getCameraCenterX();
cameraCenterY = core.cvProc.getCameraCenterY();
perspectiveCamera.setCustomARProjectionMatrix(focalPointX, focalPointY, cameraCenterX, cameraCenterY, NEAR, FAR, w, h);
perspectiveCamera.update(perspectiveCamera.projection);
// Update the game state.
gameWorld.setDelta(Gdx.graphics.getDeltaTime() * 1000);
gameWorld.getSystem(MarkerPositioningSystem.class).setMarkerData(data);
gameWorld.process();
// Decode the video frame.
videoFrame = new Pixmap(data.outFrame, 0, w * h);
videoFrameTexture = new Texture(videoFrame);
videoFrameTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
videoFrame.dispose();
// Convert the decoded frame into a renderable texture.
region = new TextureRegion(videoFrameTexture, 0, 0, w, h);
if(renderableVideoFrame == null)
renderableVideoFrame = new Sprite(region);
else
renderableVideoFrame.setRegion(region);
renderableVideoFrame.setOrigin(renderableVideoFrame.getWidth() / 2, renderableVideoFrame.getHeight() / 2);
renderableVideoFrame.setPosition(0, 0);
// Set the 3D frame buffer for rendering.
frameBuffer.begin();{
// Set OpenGL state.
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);
// Call rendering systems.
markerRenderingSystem.begin(perspectiveCamera);
markerRenderingSystem.process();
markerRenderingSystem.end();
}frameBuffer.end();
// Set the frame buffer object texture to a renderable sprite.
region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
region.flip(false, true);
if(frameBufferSprite == null)
frameBufferSprite = new Sprite(region);
else
frameBufferSprite.setRegion(region);
frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2);
frameBufferSprite.setPosition(0, 0);
// Set the position and orientation of the renderable video frame and the frame buffer.
if(!Ouya.runningOnOuya){
renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() );
renderableVideoFrame.rotate90(true);
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, 0.5f - renderableVideoFrame.getHeight());
frameBufferSprite.setSize(1.0f, frameBufferSprite.getHeight() / frameBufferSprite.getWidth() );
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight());
}else{
float xSize = Gdx.graphics.getHeight() * (w / h);
renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan());
renderableVideoFrame.rotate90(true);
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2);
frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeightWithOverscan());
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2);
}
// Set the correct camera for the device.
if(!Ouya.runningOnOuya){
core.batch.setProjectionMatrix(unitaryOrthographicCamera.combined);
}else{
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
}
// Render the video frame and the frame buffer.
core.batch.begin();{
renderableVideoFrame.draw(core.batch);
frameBufferSprite.draw(core.batch);
}core.batch.end();
// Clear the video frame from memory.
videoFrameTexture.dispose();
}
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
core.batch.begin();{
startButton.draw(core.batch, 1.0f);
if(Ouya.runningOnOuya)
ouyaOButton.draw(core.batch);
}core.batch.end();
data = null;
}
@Override
public void pause(){
automaticActionPerformer.reset();
startButton.setDisabled(false);
ignoreBackKey = false;
automaticActionEnabled = false;
}
@Override
public void dispose(){
SensorReportThread.freeInstance();
if(font != null)
font.dispose();
if(ouyaOButtonTexture != null)
ouyaOButtonTexture.dispose();
if(startButtonEnabledTexture != null)
startButtonEnabledTexture.dispose();
if(startButtonDisabledTexture != null)
startButtonDisabledTexture.dispose();
if(startButtonPressedTexture != null)
startButtonPressedTexture.dispose();
if(modelBatch != null)
modelBatch.dispose();
if(videoFrameTexture != null)
videoFrameTexture.dispose();
if(backgroundTexture != null)
backgroundTexture.dispose();
if(backgroundShader != null)
backgroundShader.dispose();
if(frameBuffer != null)
frameBuffer.dispose();
}
@Override
public void onStateSet(){
gameWorld.getSystem(CollisionDetectionSystem.class).disableCollisions();
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);
}
/*;;;;;;;;;;;;;;;;;;
; HELPER METHODS ;
;;;;;;;;;;;;;;;;;;*/
private void setUpButton(){
TextButtonStyle textButtonStyle;
FreeTypeFontGenerator fontGenerator;
FreeTypeFontParameter fontParameters;
// Create the start button background.
startButtonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png"));
startButtonEnabled9p = new NinePatch(new TextureRegion(startButtonEnabledTexture, 0, 0, startButtonEnabledTexture.getWidth(), startButtonEnabledTexture.getHeight()), 49, 49, 45, 45);
startButtonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png"));
startButtonDisabled9p = new NinePatch(new TextureRegion(startButtonDisabledTexture, 0, 0, startButtonDisabledTexture.getWidth(), startButtonDisabledTexture.getHeight()), 49, 49, 45, 45);
startButtonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png"));
startButtonPressed9p = new NinePatch(new TextureRegion(startButtonPressedTexture, 0, 0, startButtonPressedTexture.getWidth(), startButtonPressedTexture.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 start button.
textButtonStyle = new TextButtonStyle();
textButtonStyle.font = font;
textButtonStyle.up = new NinePatchDrawable(startButtonEnabled9p);
textButtonStyle.checked = new NinePatchDrawable(startButtonPressed9p);
textButtonStyle.disabled = new NinePatchDrawable(startButtonDisabled9p);
textButtonStyle.fontColor = new Color(Color.BLACK);
textButtonStyle.downFontColor = new Color(Color.WHITE);
textButtonStyle.disabledFontColor = new Color(Color.BLACK);
startButton = new TextButton("Start automatic action", textButtonStyle);
startButton.setText("Start automatic action");
startButton.setDisabled(false);
startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight());
startButton.setPosition(-(startButton.getWidth() / 2), -(Gdx.graphics.getHeight() / 2) + 10);
startButtonBBox.setPosition(startButton.getX(), startButton.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;
ouyaOButton.setPosition(startButton.getX() - ouyaOButton.getWidth() - 20, startButton.getY() + (ouyaOButton.getHeight() / 2));
}else{
ouyaOButtonTexture = null;
}
}
private void performAutomaticAction(MarkerData data){
MotorEvent event1 = null;
MotorEvent event2 = null;
automatic_action_t nextAction;
try{
if(!automaticActionPerformer.performAutomaticAction(sensorThread.getLightSensorReading(), data)){
nextAction = automaticActionPerformer.getNextAction();
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)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 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)20);
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)20);
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)-20);
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 STOP_LOOKING:
event1 = new MotorEvent();
event1.setMotor(motor_t.MOTOR_B);
event1.setPower((byte)0);
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.");
}
}else{
startButton.setDisabled(false);
ignoreBackKey = false;
automaticActionEnabled = false;
core.nextState = game_states_t.AUTOMATIC_ACTION_SUMMARY;
}
}catch(IllegalArgumentException e){
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Received IllegalArgumentException: ", e);
startButton.setDisabled(false);
ignoreBackKey = false;
automaticActionEnabled = false;
core.nextState = game_states_t.MAIN_MENU;
}catch(IllegalStateException e){
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Received IllegalStateException: ", e);
startButton.setDisabled(false);
ignoreBackKey = false;
automaticActionEnabled = false;
core.nextState = game_states_t.MAIN_MENU;
}
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INPUT PROCESSOR METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords)){
startButtonPressed = true;
}
}
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
if(!startButton.isDisabled() && startButtonPressed && startButtonBBox.contains(touchPointWorldCoords)){
startButton.setDisabled(true);
ignoreBackKey = true;
automaticActionEnabled = true;
}
}
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
if(!startButton.isDisabled() && startButtonPressed && !startButtonBBox.contains(touchPointWorldCoords)){
startButtonPressed = false;
}
}
return false;
}
@Override
public boolean keyDown(int keycode){
if(keycode == Input.Keys.BACK && !ignoreBackKey){
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 && !startButton.isDisabled()){
oButtonPressed = true;
startButton.setChecked(true);
}else if(buttonCode == Ouya.BUTTON_A && !ignoreBackKey){
aButtonPressed = true;
}
return true;
}else{
return false;
}
}
@Override
public boolean buttonUp(Controller controller, int buttonCode){
if(stateActive){
if(buttonCode == Ouya.BUTTON_O && oButtonPressed){
if(oButtonPressed){
oButtonPressed = false;
startButton.setChecked(false);
startButton.setDisabled(true);
ignoreBackKey = true;
automaticActionEnabled = true;
}
}else if(buttonCode == Ouya.BUTTON_A && aButtonPressed){
core.nextState = game_states_t.MAIN_MENU;
}
return true;
}else{
return false;
}
}
}

View File

@@ -1,330 +0,0 @@
/*
* 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.scenarios.AutomaticActionPerformerBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.ScenarioGlobals;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryOverlayBase;
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 BitmapFont font;
// Summary overlay related fields.
AutomaticActionPerformerBase automaticActionPerformer;
SummaryOverlayBase summaryOverlay;
// Button touch helper fields.
private boolean continueButtonTouched;
private int continueButtonTouchPointer;
public AutomaticActionSummaryState(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;
automaticActionPerformer = ScenarioGlobals.getAutomaticActionPerformer();
summaryOverlay = ScenarioGlobals.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);
ouyaOButton.setPosition(continueButton.getX() - ouyaOButton.getWidth() - 20, continueButton.getY() + (ouyaOButton.getHeight() / 2));
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;
}
}
}

View File

@@ -26,16 +26,27 @@ import ve.ucv.ciens.ccg.nxtar.utils.Size;
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.Pixmap;
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.TextureRegion;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
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 CameraCalibrationState extends BaseState{
private static final String TAG = "CAMERA_CALIBRATION_STATE";
@@ -43,7 +54,6 @@ public class CameraCalibrationState extends BaseState{
private static final String SHADER_PATH = "shaders/bckg/bckg";
private NxtARCore core;
private boolean cameraCalibrated;
private float u_scaling[];
protected Sprite background;
@@ -58,16 +68,34 @@ public class CameraCalibrationState extends BaseState{
private Sprite renderableVideoFrame;
private Pixmap videoFrame;
// Gui components.
private TextButton takeSampleButton;
private Rectangle takeSampleButtonBBox;
private Texture buttonEnabledTexture;
private Texture buttonDisabledTexture;
private Texture buttonPressedTexture;
private NinePatch buttonEnabled9p;
private NinePatch buttonDisabled9p;
private NinePatch buttonPressed9p;
private BitmapFont font;
// Button touch helper fields.
private boolean takeSampleButtonTouched;
private int takeSampleButtonPointer;
// Monitors.
private VideoFrameMonitor frameMonitor;
private float[][] calibrationSamples;
private boolean takeSample;
private int lastSampleTaken;
public CameraCalibrationState(final NxtARCore core){
TextButtonStyle tbs;
FreeTypeFontGenerator generator;
this.core = core;
frameMonitor = VideoFrameMonitor.getInstance();
cameraCalibrated = false;
// Set up the cameras.
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
@@ -94,6 +122,42 @@ public class CameraCalibrationState extends BaseState{
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;
// Set up the sampling button.
// Create the font.
generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf"));
font = generator.generateFont(ProjectConstants.MENU_BUTTON_FONT_SIZE, ProjectConstants.FONT_CHARS, false);
generator.dispose();
// Load the textures.
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 button style.
tbs = new TextButtonStyle();
tbs.font = font;
tbs.up = new NinePatchDrawable(buttonEnabled9p);
tbs.checked = new NinePatchDrawable(buttonPressed9p);
tbs.disabled = new NinePatchDrawable(buttonDisabled9p);
tbs.disabledFontColor = new Color(0, 0, 0, 1);
// Create the button itself.
takeSampleButton = new TextButton("Take calibration sample", tbs);
takeSampleButton.setText("Take calibration sample");
takeSampleButton.setDisabled(true);
takeSampleButtonBBox = new Rectangle(0, 0, takeSampleButton.getWidth(), takeSampleButton.getHeight());
takeSampleButton.setPosition(-(takeSampleButton.getWidth() / 2), -(Gdx.graphics.getHeight()/2) - 1 + (takeSampleButton.getHeight() / 2));
takeSampleButtonBBox.setPosition(takeSampleButton.getX(), takeSampleButton.getY());
// Set up the touch collision detection variables.
win2world = new Vector3(0.0f, 0.0f, 0.0f);
touchPointWorldCoords = new Vector2();
takeSampleButtonTouched = false;
takeSampleButtonPointer = -1;
// Initialize the calibration samples vector.
calibrationSamples = new float[ProjectConstants.CALIBRATION_SAMPLES][];
for(int i = 0; i < calibrationSamples.length; i++){
@@ -107,8 +171,8 @@ public class CameraCalibrationState extends BaseState{
Gdx.input.setCatchBackKey(true);
Gdx.input.setCatchMenuKey(true);
takeSample = false;
lastSampleTaken = 0;
cameraCalibrated = false;
for(int i = 0; i < calibrationSamples.length; i++){
for(int j = 0; j < calibrationSamples[i].length; j++){
@@ -122,6 +186,7 @@ public class CameraCalibrationState extends BaseState{
@Override
public void render(float delta){
String msg;
byte[] frame;
byte[] prevFrame = null;
Size dimensions = null;
@@ -144,11 +209,25 @@ public class CameraCalibrationState extends BaseState{
// Fetch the current video frame.
frame = frameMonitor.getCurrentFrame();
// Apply the undistortion method if the camera has been calibrated already.
/*if(core.cvProc.isCameraCalibrated()){
frame = core.cvProc.undistortFrame(frame);
}*/
// Find the calibration points in the video frame.
CalibrationData data = core.cvProc.findCalibrationPattern(frame);
// Disable the sampling button if the calibration pattern was not found.
if(data.calibrationPoints != null && !core.cvProc.isCameraCalibrated()){
takeSampleButton.setDisabled(false);
}else{
takeSampleButton.setDisabled(true);
}
// If the user requested a sample be taken.
if(!cameraCalibrated && data.calibrationPoints != null){
if(takeSample && !core.cvProc.isCameraCalibrated() && data.calibrationPoints != null){
// Disable sample taking.
takeSample = false;
Gdx.app.log(TAG, CLASS_NAME + ".render(): Sample taken.");
// Save the calibration points to the samples array.
@@ -161,14 +240,17 @@ public class CameraCalibrationState extends BaseState{
// Move to the next sample.
lastSampleTaken++;
msg = Integer.toString(lastSampleTaken) + " samples taken. ";
msg += Integer.toString(ProjectConstants.CALIBRATION_SAMPLES - lastSampleTaken) + " samples left.";
core.toast(msg, false);
// If enough samples has been taken then calibrate the camera.
if(lastSampleTaken == ProjectConstants.CALIBRATION_SAMPLES){
Gdx.app.log(TAG, CLASS_NAME + "render(): Last sample taken.");
core.cvProc.calibrateCamera(calibrationSamples, frame);
cameraCalibrated = core.cvProc.isCameraCalibrated();
core.onCameraCalibrated();
core.nextState = game_states_t.MAIN_MENU;
msg = "Camera successfully calibrated";
core.toast(msg, true);
}
}
@@ -197,8 +279,11 @@ public class CameraCalibrationState extends BaseState{
}
// Render the frame.
if(!Ouya.runningOnOuya) core.batch.setProjectionMatrix(camera.combined);
else core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
if(!Ouya.runningOnOuya){
core.batch.setProjectionMatrix(camera.combined);
}else{
core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
}
core.batch.begin();{
renderableVideoFrame.draw(core.batch);
}core.batch.end();
@@ -207,10 +292,35 @@ public class CameraCalibrationState extends BaseState{
videoFrameTexture.dispose();
}
// Render the user interface.
if(!Ouya.runningOnOuya){
core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
core.batch.begin();{
takeSampleButton.draw(core.batch, 1.0f);
}core.batch.end();
}else{
// TODO: Render OUYA gui.
}
// Save this frame as previous to avoid processing the same frame twice when network latency is high.
prevFrame = frame;
}
@Override
public void resize(int width, int height){ }
@Override
public void show(){ }
@Override
public void hide(){ }
@Override
public void pause(){ }
@Override
public void resume(){ }
@Override
public void dispose(){
if(videoFrameTexture != null)
@@ -231,4 +341,74 @@ public class CameraCalibrationState extends BaseState{
}
return false;
}
@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(!takeSampleButton.isDisabled() && takeSampleButtonBBox.contains(touchPointWorldCoords) && !takeSampleButtonTouched){
takeSampleButton.setChecked(true);
takeSampleButtonTouched = true;
takeSampleButtonPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Sample 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(!takeSampleButton.isDisabled() && takeSampleButtonBBox.contains(touchPointWorldCoords) && takeSampleButtonTouched){
takeSampleButton.setChecked(false);
takeSampleButtonTouched = false;
takeSampleButtonPointer = -1;
takeSample = true;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Sample button released.");
}
return true;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer){
unprojectTouch(screenX, screenY);
if(!takeSampleButton.isDisabled() && takeSampleButtonTouched && pointer == takeSampleButtonPointer && !takeSampleButtonBBox.contains(touchPointWorldCoords)){
takeSampleButtonPointer = -1;
takeSampleButtonTouched = false;
takeSampleButton.setChecked(false);
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Sample button released.");
}
return true;
}
@Override
public boolean buttonDown(Controller controller, int buttonCode){
// TODO: Handle OUYA controls.
return false;
}
@Override
public boolean buttonUp(Controller controller, int buttonCode){
// TODO: Handle OUYA controls.
return false;
}
@Override
public boolean axisMoved(Controller controller, int axisCode, float value){
// TODO: Handle OUYA controls.
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,327 +0,0 @@
/*
* 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);
ouyaOButton.setPosition(continueButton.getX() - ouyaOButton.getWidth() - 20, continueButton.getY() + (ouyaOButton.getHeight() / 2));
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

@@ -1,348 +1,318 @@
/*
* 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.game_states_t;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
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 abstract class MainMenuStateBase extends BaseState{
protected static final String TAG = "MAIN_MENU";
private static final String CLASS_NAME = MainMenuStateBase.class.getSimpleName();
private static final String SHADER_PATH = "shaders/movingBckg/movingBckg";
protected final int NUM_MENU_BUTTONS = 3;
// Helper fields.
protected boolean clientConnected;
protected boolean cameraCalibrated;
protected boolean assetsLoaded;
private float u_scaling[];
private float u_displacement;
// Buttons and other gui components.
protected TextButton startButton;
protected Rectangle startButtonBBox;
protected TextButton calibrationButton;
protected Rectangle calibrationButtonBBox;
protected TextButton autoButton;
protected Rectangle autoButtonBBox;
protected Sprite cameraCalibratedLedOn;
protected Sprite cameraCalibratedLedOff;
protected Sprite assetsLoadedLedOn;
protected Sprite assetsLoadedLedOff;
protected Sprite background;
// Graphic data for the start button.
private Texture menuButtonEnabledTexture;
private Texture menuButtonDisabledTexture;
private Texture menuButtonPressedTexture;
private NinePatch menuButtonEnabled9p;
private NinePatch menuButtonDisabled9p;
private NinePatch menuButtonPressed9p;
private BitmapFont font;
// Other graphics.
private Texture ledOffTexture;
private Texture ledOnTexture;
private Texture backgroundTexture;
private ShaderProgram backgroundShader;
// Button touch helper fields.
protected boolean startButtonTouched;
protected int startButtonTouchPointer;
protected boolean calibrationButtonTouched;
protected int calibrationButtonTouchPointer;
protected boolean autoButtonTouched;
protected int autoButtonTouchPointer;
public MainMenuStateBase(){
TextureRegion region;
TextButtonStyle textButtonStyle;
FreeTypeFontGenerator fontGenerator;
FreeTypeFontParameter fontParameters;
this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// 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);
// 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 buttons.
textButtonStyle = new TextButtonStyle();
textButtonStyle.font = font;
textButtonStyle.up = new NinePatchDrawable(menuButtonEnabled9p);
textButtonStyle.checked = new NinePatchDrawable(menuButtonPressed9p);
textButtonStyle.disabled = new NinePatchDrawable(menuButtonDisabled9p);
textButtonStyle.fontColor = new Color(Color.BLACK);
textButtonStyle.downFontColor = new Color(Color.WHITE);
textButtonStyle.disabledFontColor = new Color(Color.BLACK);
startButton = new TextButton("Manual control", textButtonStyle);
startButton.setText("Manual control");
startButton.setDisabled(true);
startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight());
calibrationButton = new TextButton("Calibrate camera", textButtonStyle);
calibrationButton.setText("Calibrate camera");
calibrationButton.setDisabled(true);
calibrationButtonBBox = new Rectangle(0, 0, calibrationButton.getWidth(), calibrationButton.getHeight());
autoButton = new TextButton("Automatic action", textButtonStyle);
autoButton.setText("Automatic action");
autoButton.setDisabled(true);
autoButtonBBox = new Rectangle(0, 0, autoButton.getWidth(), autoButton.getHeight());
// Create the connection leds.
ledOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png");
ledOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png");
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);
// 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);
region = new TextureRegion(backgroundTexture);
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();
startButtonTouched = false;
startButtonTouchPointer = -1;
calibrationButtonTouched = false;
calibrationButtonTouchPointer = -1;
autoButtonTouched = false;
autoButtonTouchPointer = -1;
clientConnected = false;
cameraCalibrated = false;
assetsLoaded = false;
stateActive = false;
}
@Override
public abstract void render(float delta);
@Override
public void dispose(){
menuButtonEnabledTexture.dispose();
menuButtonDisabledTexture.dispose();
menuButtonPressedTexture.dispose();
ledOnTexture.dispose();
ledOffTexture.dispose();
backgroundTexture.dispose();
if(backgroundShader != null) backgroundShader.dispose();
font.dispose();
}
protected 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);
}
public void onClientConnected(){
clientConnected = true;
calibrationButton.setDisabled(false);
}
public void onCameraCalibrated(){
cameraCalibrated = true;
enableGameButtons();
}
public void onAssetsLoaded(){
assetsLoaded = true;
enableGameButtons();
}
private void enableGameButtons(){
startButton.setDisabled(!(cameraCalibrated && assetsLoaded));
autoButton.setDisabled(!(cameraCalibrated && assetsLoaded));
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && (!calibrationButtonTouched && !autoButtonTouched)){
startButton.setChecked(true);
startButtonTouched = true;
startButtonTouchPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed.");
}else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && (!startButtonTouched && !autoButtonTouched)){
calibrationButton.setChecked(true);
calibrationButtonTouched = true;
calibrationButtonTouchPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button pressed.");
}else if(!autoButton.isDisabled() && autoButtonBBox.contains(touchPointWorldCoords) && (!startButtonTouched && !calibrationButtonTouched)){
autoButton.setChecked(true);
autoButtonTouched = true;
autoButtonTouchPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Auto 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(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched){
startButton.setChecked(false);
startButtonTouched = false;
startButtonTouchPointer = -1;
core.nextState = game_states_t.IN_GAME;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released.");
}else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && calibrationButtonTouched){
calibrationButton.setChecked(false);
calibrationButtonTouched = false;
calibrationButtonTouchPointer = -1;
core.nextState = game_states_t.CALIBRATION;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button released.");
}else if(!autoButton.isDisabled() && autoButtonBBox.contains(touchPointWorldCoords) && autoButtonTouched){
autoButton.setChecked(false);
autoButtonTouched = false;
autoButtonTouchPointer = -1;
core.nextState = game_states_t.AUTOMATIC_ACTION;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Auto button released.");
}
return true;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer){
unprojectTouch(screenX, screenY);
if(!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer && !startButtonBBox.contains(touchPointWorldCoords)){
startButtonTouchPointer = -1;
startButtonTouched = false;
startButton.setChecked(false);
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released.");
}else if(!calibrationButton.isDisabled() && calibrationButtonTouched && pointer == calibrationButtonTouchPointer && !calibrationButtonBBox.contains(touchPointWorldCoords)){
calibrationButtonTouchPointer = -1;
calibrationButtonTouched = false;
calibrationButton.setChecked(false);
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released.");
}else if(!autoButton.isDisabled() && autoButtonTouched && pointer == autoButtonTouchPointer && !autoButtonBBox.contains(touchPointWorldCoords)){
autoButtonTouchPointer = -1;
autoButtonTouched = false;
autoButton.setChecked(false);
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Auto button released.");
}
return true;
}
@Override
public boolean keyDown(int keycode){
if(keycode == Input.Keys.BACK){
Gdx.app.exit();
return true;
}
return false;
}
}
/*
* 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.game_states_t;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
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.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 abstract class MainMenuStateBase extends BaseState{
protected static final String TAG = "MAIN_MENU";
private static final String CLASS_NAME = MainMenuStateBase.class.getSimpleName();
private static final String SHADER_PATH = "shaders/bckg/bckg";
protected final int NUM_MENU_BUTTONS = 2;
// Helper fields.
protected boolean clientConnected;
private float u_scaling[];
// Buttons and other gui components.
protected TextButton startButton;
protected Rectangle startButtonBBox;
protected Sprite clientConnectedLedOn;
protected Sprite clientConnectedLedOff;
protected TextButton calibrationButton;
protected Rectangle calibrationButtonBBox;
protected Sprite cameraCalibratedLedOn;
protected Sprite cameraCalibratedLedOff;
protected Sprite background;
// Graphic data for the start button.
private Texture menuButtonEnabledTexture;
private Texture menuButtonDisabledTexture;
private Texture menuButtonPressedTexture;
private NinePatch menuButtonEnabled9p;
private NinePatch menuButtonDisabled9p;
private NinePatch menuButtonPressed9p;
private BitmapFont font;
// Other graphics.
private Texture cameraCalibratedLedOffTexture;
private Texture cameraCalibratedLedOnTexture;
private Texture clientConnectedLedOffTexture;
private Texture clientConnectedLedOnTexture;
private Texture backgroundTexture;
private ShaderProgram backgroundShader;
// Button touch helper fields.
protected boolean startButtonTouched;
protected int startButtonTouchPointer;
protected boolean calibrationButtonTouched;
protected int calibrationButtonTouchPointer;
public MainMenuStateBase(){
TextureRegion region;
TextButtonStyle tbs;
FreeTypeFontGenerator generator;
this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// 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);
// Create the start button font.
generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf"));
font = generator.generateFont(ProjectConstants.MENU_BUTTON_FONT_SIZE, ProjectConstants.FONT_CHARS, false);
generator.dispose();
// Create the start button.
tbs = new TextButtonStyle();
tbs.font = font;
tbs.up = new NinePatchDrawable(menuButtonEnabled9p);
tbs.checked = new NinePatchDrawable(menuButtonPressed9p);
tbs.disabled = new NinePatchDrawable(menuButtonDisabled9p);
tbs.disabledFontColor = new Color(0, 0, 0, 1);
startButton = new TextButton("Start server", tbs);
startButton.setText("Start game");
startButton.setDisabled(true);
startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight());
// Create the calibration button.
calibrationButton = new TextButton("Calibrate camera", tbs);
calibrationButton.setText("Calibrate camera");
calibrationButton.setDisabled(true);
calibrationButtonBBox = new Rectangle(0, 0, calibrationButton.getWidth(), calibrationButton.getHeight());
// Create the connection leds.
clientConnectedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png");
region = new TextureRegion(clientConnectedLedOnTexture);
clientConnectedLedOn = new Sprite(region);
clientConnectedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png");
region = new TextureRegion(clientConnectedLedOffTexture);
clientConnectedLedOff = new Sprite(region);
cameraCalibratedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png");
region = new TextureRegion(cameraCalibratedLedOnTexture);
cameraCalibratedLedOn = new Sprite(region);
cameraCalibratedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png");
region = new TextureRegion(cameraCalibratedLedOffTexture);
cameraCalibratedLedOff = new Sprite(region);
// 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);
region = new TextureRegion(backgroundTexture);
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;
win2world = new Vector3(0.0f, 0.0f, 0.0f);
touchPointWorldCoords = new Vector2();
startButtonTouched = false;
startButtonTouchPointer = -1;
calibrationButtonTouched = false;
calibrationButtonTouchPointer = -1;
clientConnected = false;
stateActive = false;
}
@Override
public abstract void render(float delta);
@Override
public void resize(int width, int height){ }
@Override
public void show(){ }
@Override
public void hide(){ }
@Override
public void pause(){ }
@Override
public void resume(){ }
@Override
public void dispose(){
menuButtonEnabledTexture.dispose();
menuButtonDisabledTexture.dispose();
menuButtonPressedTexture.dispose();
clientConnectedLedOnTexture.dispose();
clientConnectedLedOffTexture.dispose();
cameraCalibratedLedOnTexture.dispose();
cameraCalibratedLedOffTexture.dispose();
backgroundTexture.dispose();
if(backgroundShader != null) backgroundShader.dispose();
font.dispose();
}
protected void drawBackground(SpriteBatch batch){
if(backgroundShader != null){
batch.setShader(backgroundShader);
backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2);
}
background.draw(batch);
if(backgroundShader != null) batch.setShader(null);
}
@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);
}
public void onClientConnected(){
clientConnected = true;
startButton.setDisabled(false);
calibrationButton.setDisabled(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(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && !calibrationButtonTouched){
startButton.setChecked(true);
startButtonTouched = true;
startButtonTouchPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed.");
}else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && !startButtonTouched){
calibrationButton.setChecked(true);
calibrationButtonTouched = true;
calibrationButtonTouchPointer = pointer;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration 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(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched){
startButton.setChecked(false);
startButtonTouched = false;
startButtonTouchPointer = -1;
core.nextState = game_states_t.IN_GAME;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released.");
}else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && calibrationButtonTouched){
calibrationButton.setChecked(false);
calibrationButtonTouched = false;
calibrationButtonTouchPointer = -1;
core.nextState = game_states_t.CALIBRATION;
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button released.");
}
return true;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer){
unprojectTouch(screenX, screenY);
if(!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer && !startButtonBBox.contains(touchPointWorldCoords)){
startButtonTouchPointer = -1;
startButtonTouched = false;
startButton.setChecked(false);
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released.");
}else if(!calibrationButton.isDisabled() && calibrationButtonTouched && pointer == calibrationButtonTouchPointer && !calibrationButtonBBox.contains(touchPointWorldCoords)){
calibrationButtonTouchPointer = -1;
calibrationButtonTouched = false;
calibrationButton.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){
// Ignore.
return true;
}
return false;
}
}

View File

@@ -1,209 +1,171 @@
/*
* 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.utils.Utils;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class OuyaMainMenuState extends MainMenuStateBase{
private static final String CLASS_NAME = OuyaMainMenuState.class.getSimpleName();
private Texture ouyaOButtonTexture;
private Sprite ouyaOButton;
private boolean oButtonPressed;
private int oButtonSelection;
private float ledYPos;
public OuyaMainMenuState(final NxtARCore core) throws IllegalArgumentException{
super();
if(core == null)
throw new IllegalArgumentException(CLASS_NAME + ": Core is null.");
this.core = core;
// Set buttons.
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
calibrationButton.setPosition(-(calibrationButton.getWidth() / 2), (startButton.getY() + startButton.getHeight()) + 10);
calibrationButtonBBox.setPosition(calibrationButton.getX(), calibrationButton.getY());
autoButton.setPosition(-(autoButton.getWidth() / 2), (startButton.getY() - startButton.getHeight()) - 10);
autoButtonBBox.setPosition(autoButton.getX(), autoButton.getY());
//Set leds.
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);
cameraCalibratedLedOff.setPosition(-cameraCalibratedLedOff.getWidth() - 5, ledYPos);
assetsLoadedLedOn.setSize(assetsLoadedLedOn.getWidth() * 0.5f, assetsLoadedLedOn.getHeight() * 0.5f);
assetsLoadedLedOn.setPosition(5, ledYPos);
assetsLoadedLedOff.setSize(assetsLoadedLedOff.getWidth() * 0.5f, assetsLoadedLedOff.getHeight() * 0.5f);
assetsLoadedLedOff.setPosition(5, ledYPos);
// Set OUYA's O button.
ouyaOButtonTexture = new Texture("data/gfx/gui/OUYA_O.png");
TextureRegion region = new TextureRegion(ouyaOButtonTexture, ouyaOButtonTexture.getWidth(), ouyaOButtonTexture.getHeight());
ouyaOButton = new Sprite(region);
ouyaOButton.setSize(ouyaOButton.getWidth() * 0.6f, ouyaOButton.getHeight() * 0.6f);
oButtonSelection = 0;
oButtonPressed = 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();
// Render leds.
if(cameraCalibrated) cameraCalibratedLedOn.draw(core.batch);
else cameraCalibratedLedOff.draw(core.batch);
if(assetsLoaded) assetsLoadedLedOn.draw(core.batch);
else assetsLoadedLedOff.draw(core.batch);
// Render buttons.
startButton.draw(core.batch, 1.0f);
calibrationButton.draw(core.batch, 1.0f);
autoButton.draw(core.batch, 1.0f);
// Render O button.
if(oButtonSelection == 0){
ouyaOButton.setPosition(startButton.getX() - ouyaOButton.getWidth() - 20, startButton.getY() + (ouyaOButton.getHeight() / 2));
}else if(oButtonSelection == 1){
ouyaOButton.setPosition(calibrationButton.getX() - ouyaOButton.getWidth() - 20, calibrationButton.getY() + (ouyaOButton.getHeight() / 2));
}else if(oButtonSelection == 2){
ouyaOButton.setPosition(autoButton.getX() - ouyaOButton.getWidth() - 20, autoButton.getY() + (ouyaOButton.getHeight() / 2));
}
ouyaOButton.draw(core.batch);
}core.batch.end();
}
@Override
public void dispose(){
super.dispose();
ouyaOButtonTexture.dispose();
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER LISTENER METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean buttonDown(Controller controller, int buttonCode){
if(stateActive){
if(buttonCode == Ouya.BUTTON_O){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): O button pressed.");
if(oButtonSelection == 0){
if(!clientConnected){
core.toast("Can't start the game. No client is connected.", true);
}else if(!core.cvProc.isCameraCalibrated()){
core.toast("Can't start the game. Camera is not calibrated.", true);
}else{
oButtonPressed = true;
startButton.setChecked(true);
}
}else if(oButtonSelection == 1){
if(!clientConnected){
core.toast("Can't calibrate the camera. No client is connected.", true);
}else{
oButtonPressed = true;
calibrationButton.setChecked(true);
}
}else if(oButtonSelection == 2){
if(!clientConnected){
core.toast("Can't launch automatic action. No client is connected.", true);
}else{
oButtonPressed = true;
autoButton.setChecked(true);
}
}
}else if(buttonCode == Ouya.BUTTON_DPAD_UP){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad up button pressed.");
oButtonSelection = (oButtonSelection + 1) % NUM_MENU_BUTTONS;
}else if(buttonCode == Ouya.BUTTON_DPAD_DOWN){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad down button pressed.");
oButtonSelection = oButtonSelection - 1 < 0 ? NUM_MENU_BUTTONS - 1 : oButtonSelection - 1;
}
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;
if(oButtonSelection == 0){
startButton.setChecked(false);
core.nextState = game_states_t.IN_GAME;
}else if(oButtonSelection == 1){
calibrationButton.setChecked(false);
core.nextState = game_states_t.CALIBRATION;
}else if(oButtonSelection == 2){
autoButton.setChecked(false);
core.nextState = game_states_t.AUTOMATIC_ACTION;
}
}
}
return true;
}else{
return false;
}
}
@Override
public boolean axisMoved(Controller controller, int axisCode, float value){
if(Math.abs(value) > 0.99f){
if(axisCode == Ouya.AXIS_LEFT_Y && value < 0.0f){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad up button pressed.");
oButtonSelection = (oButtonSelection + 1) % NUM_MENU_BUTTONS;
}else if(axisCode == Ouya.AXIS_LEFT_Y && value >= 0.0f){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad down button pressed.");
oButtonSelection = oButtonSelection - 1 < 0 ? NUM_MENU_BUTTONS - 1 : oButtonSelection - 1;
}
return true;
}
return false;
}
}
/*
* 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 com.badlogic.gdx.Gdx;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class OuyaMainMenuState extends MainMenuStateBase{
private static final String CLASS_NAME = OuyaMainMenuState.class.getSimpleName();
private Texture ouyaOButtonTexture;
private Sprite ouyaOButton;
private boolean oButtonPressed;
private int oButtonSelection;
public OuyaMainMenuState(final NxtARCore core){
super();
this.core = core;
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
calibrationButton.setPosition(-(calibrationButton.getWidth() / 2), (startButton.getY() + startButton.getHeight()) + 10);
calibrationButtonBBox.setPosition(calibrationButton.getX(), calibrationButton.getY());
float ledYPos = (-(Gdx.graphics.getHeight() / 2) * 0.5f) + (calibrationButton.getY() * 0.5f);
clientConnectedLedOn.setSize(clientConnectedLedOn.getWidth() * 0.5f, clientConnectedLedOn.getHeight() * 0.5f);
clientConnectedLedOn.setPosition(-(clientConnectedLedOn.getWidth() / 2), ledYPos);
clientConnectedLedOff.setSize(clientConnectedLedOff.getWidth() * 0.5f, clientConnectedLedOff.getHeight() * 0.5f);
clientConnectedLedOff.setPosition(-(clientConnectedLedOff.getWidth() / 2), ledYPos);
// TODO: Set calibration led attributes.
ouyaOButtonTexture = new Texture("data/gfx/gui/OUYA_O.png");
TextureRegion region = new TextureRegion(ouyaOButtonTexture, ouyaOButtonTexture.getWidth(), ouyaOButtonTexture.getHeight());
ouyaOButton = new Sprite(region);
ouyaOButton.setSize(ouyaOButton.getWidth() * 0.6f, ouyaOButton.getHeight() * 0.6f);
oButtonSelection = 0;
oButtonPressed = false;
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
core.batch.begin();{
core.batch.disableBlending();
drawBackground(core.batch);
core.batch.enableBlending();
if(clientConnected){
clientConnectedLedOn.draw(core.batch);
}else{
clientConnectedLedOff.draw(core.batch);
}
// TODO: Render calibration leds.
startButton.draw(core.batch, 1.0f);
calibrationButton.draw(core.batch, 1.0f);
if(oButtonSelection == 0){
ouyaOButton.setPosition(startButton.getX() - ouyaOButton.getWidth() - 20, startButton.getY() + (ouyaOButton.getHeight() / 2));
}else if(oButtonSelection == 1){
ouyaOButton.setPosition(calibrationButton.getX() - ouyaOButton.getWidth() - 20, calibrationButton.getY() + (ouyaOButton.getHeight() / 2));
}
ouyaOButton.draw(core.batch);
}core.batch.end();
}
@Override
public void dispose(){
super.dispose();
ouyaOButtonTexture.dispose();
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BEGIN CONTROLLER LISTENER METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean buttonDown(Controller controller, int buttonCode){
// TODO: Test this.
if(stateActive){
if(buttonCode == Ouya.BUTTON_O){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): O button pressed.");
if(oButtonSelection == 0){
if(!clientConnected){
core.toast("Can't start the game. No client is connected.", true);
}else{
oButtonPressed = true;
startButton.setChecked(true);
}
}else if(oButtonSelection == 1){
if(!clientConnected){
core.toast("Can't calibrate the camera. No client is connected.", true);
}else{
oButtonPressed = true;
calibrationButton.setChecked(true);
}
}
}else if(buttonCode == Ouya.BUTTON_DPAD_UP){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad up button pressed.");
oButtonSelection = oButtonSelection - 1 < 0 ? NUM_MENU_BUTTONS - 1 : oButtonSelection - 1;
}else if(buttonCode == Ouya.BUTTON_DPAD_DOWN){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): Dpad down button pressed.");
oButtonSelection = (oButtonSelection + 1) % NUM_MENU_BUTTONS;
}
return true;
}else{
return false;
}
}
@Override
public boolean buttonUp(Controller controller, int buttonCode){
// TODO: Test this.
if(stateActive){
if(buttonCode == Ouya.BUTTON_O){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown(): O button released.");
if(oButtonPressed){
oButtonPressed = false;
if(oButtonSelection == 0){
startButton.setChecked(false);
core.nextState = game_states_t.IN_GAME;
}else if(oButtonSelection == 1){
calibrationButton.setChecked(false);
core.nextState = game_states_t.IN_GAME;
}
}
}
return true;
}else{
return false;
}
}
}

View File

@@ -0,0 +1,202 @@
/*
* 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 com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.PovDirection;
import com.badlogic.gdx.math.Vector3;
public class PauseState extends BaseState {
public PauseState(final NxtARCore core){
this.core = core;
}
@Override
public void render(float delta) {
// TODO Auto-generated method stub
}
@Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void show() {
// TODO Auto-generated method stub
}
@Override
public void hide() {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
/*;;;;;;;;;;;;;;;;;;
; HELPER METHODS ;
;;;;;;;;;;;;;;;;;;*/
@Override
public void onStateSet(){
}
@Override
public void onStateUnset(){
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BEGIN INPUT PROCESSOR METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean keyDown(int keycode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; END INPUT PROCESSOR METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BEGIN CONTROLLER LISTENER METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
@Override
public void connected(Controller controller) {
// TODO Auto-generated method stub
}
@Override
public void disconnected(Controller controller) {
// TODO Auto-generated method stub
}
@Override
public boolean buttonDown(Controller controller, int buttonCode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean buttonUp(Controller controller, int buttonCode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean axisMoved(Controller controller, int axisCode, float value) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean povMoved(Controller controller, int povCode,
PovDirection value) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean xSliderMoved(Controller controller, int sliderCode,
boolean value) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean ySliderMoved(Controller controller, int sliderCode,
boolean value) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean accelerometerMoved(Controller controller,
int accelerometerCode, Vector3 value) {
// TODO Auto-generated method stub
return false;
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; END CONTROLLER LISTENER METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
}

View File

@@ -1,330 +0,0 @@
/*
* 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.scenarios.ScenarioGlobals;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryOverlayBase;
import ve.ucv.ciens.ccg.nxtar.systems.PlayerSystemBase;
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 ScenarioEndSummaryState extends BaseState {
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.
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;
// Summary overlay related fields.
PlayerSystemBase playerSystem;
SummaryOverlayBase summaryOverlay;
// Button touch helper fields.
private boolean continueButtonTouched;
private int continueButtonTouchPointer;
public ScenarioEndSummaryState(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;
playerSystem = ScenarioGlobals.getPlayerSystem();
summaryOverlay = ScenarioGlobals.getScenarioSummaryOverlay();
// 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);
ouyaOButton.setPosition(continueButton.getX() - ouyaOButton.getWidth() - 20, continueButton.getY() + (ouyaOButton.getHeight() / 2));
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, playerSystem.getPlayerSummary());
// 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;
}
}
}

View File

@@ -1,83 +1,71 @@
/*
* 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.utils.Utils;
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) throws IllegalArgumentException{
super();
if(core == null)
throw new IllegalArgumentException(CLASS_NAME + ": Core is null.");
this.core = core;
// Set buttons.
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
calibrationButton.setPosition(-(calibrationButton.getWidth() / 2), (startButton.getY() + startButton.getHeight()) + 10);
calibrationButtonBBox.setPosition(calibrationButton.getX(), calibrationButton.getY());
autoButton.setPosition(-(autoButton.getWidth() / 2), (startButton.getY() - startButton.getHeight()) - 10);
autoButtonBBox.setPosition(autoButton.getX(), autoButton.getY());
// Set leds.
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);
cameraCalibratedLedOff.setPosition(-cameraCalibratedLedOff.getWidth() - 5, ledYPos);
assetsLoadedLedOn.setSize(assetsLoadedLedOn.getWidth() * 0.5f, assetsLoadedLedOn.getHeight() * 0.5f);
assetsLoadedLedOn.setPosition(5, ledYPos);
assetsLoadedLedOff.setSize(assetsLoadedLedOff.getWidth() * 0.5f, assetsLoadedLedOff.getHeight() * 0.5f);
assetsLoadedLedOff.setPosition(5, ledYPos);
}
@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();
// Render leds.
if(cameraCalibrated) cameraCalibratedLedOn.draw(core.batch);
else cameraCalibratedLedOff.draw(core.batch);
if(assetsLoaded) assetsLoadedLedOn.draw(core.batch);
else assetsLoadedLedOff.draw(core.batch);
// Render buttons.
startButton.draw(core.batch, 1.0f);
calibrationButton.draw(core.batch, 1.0f);
autoButton.draw(core.batch, 1.0f);
}core.batch.end();
}
}
/*
* 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 com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
public class TabletMainMenuState extends MainMenuStateBase{
public TabletMainMenuState(final NxtARCore core){
super();
this.core = core;
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
calibrationButton.setPosition(-(calibrationButton.getWidth() / 2), (startButton.getY() + startButton.getHeight()) + 10);
calibrationButtonBBox.setPosition(calibrationButton.getX(), calibrationButton.getY());
float ledYPos = (-(Gdx.graphics.getHeight() / 2) * 0.5f) + (calibrationButton.getY() * 0.5f);
clientConnectedLedOn.setSize(clientConnectedLedOn.getWidth() * 0.5f, clientConnectedLedOn.getHeight() * 0.5f);
clientConnectedLedOn.setPosition(-(clientConnectedLedOn.getWidth() / 2), ledYPos);
clientConnectedLedOff.setSize(clientConnectedLedOff.getWidth() * 0.5f, clientConnectedLedOff.getHeight() * 0.5f);
clientConnectedLedOff.setPosition(-(clientConnectedLedOff.getWidth() / 2), ledYPos);
// TODO: Set calibration led attributes.
}
@Override
public void render(float delta){
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
core.batch.begin();{
core.batch.disableBlending();
drawBackground(core.batch);
core.batch.enableBlending();
if(clientConnected){
clientConnectedLedOn.draw(core.batch);
}else{
clientConnectedLedOff.draw(core.batch);
}
// TODO: Render calibration led.
startButton.draw(core.batch, 1.0f);
calibrationButton.draw(core.batch, 1.0f);
}core.batch.end();
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.AnimationComponent;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
public class AnimationSystem extends EntityProcessingSystem {
public static final int NO_ANIMATION = -1;
@Mapper ComponentMapper<AnimationComponent> animationMapper;
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
@SuppressWarnings("unchecked")
public AnimationSystem(){
super(Aspect.getAspectForAll(AnimationComponent.class, VisibilityComponent.class));
}
@Override
protected void process(Entity e) {
AnimationComponent animation = animationMapper.get(e);
VisibilityComponent visibility = visibilityMapper.get(e);
int loopCount = animation.loop ? -1 : 1;
if(animation.current != animation.next && animation.next >= 0 && animation.next < animation.animationsIds.size()){
animation.current = animation.next;
if(animation.controller.current == null){
animation.controller.setAnimation(animation.animationsIds.get(animation.next), loopCount, 1, null);
}else{
animation.controller.animate(animation.animationsIds.get(animation.next), loopCount, 1, null, 0.1f);
}
if(animation.collisionController != null){
if(animation.collisionController.current == null){
animation.collisionController.setAnimation(animation.animationsIds.get(animation.next), loopCount, 1, null);
}else{
animation.collisionController.animate(animation.animationsIds.get(animation.next), loopCount, 1, null, 0.1f);
}
}
}
if(visibility.visible){
animation.controller.update(Gdx.graphics.getDeltaTime());
if(animation.collisionController != null)
animation.collisionController.update(Gdx.graphics.getDeltaTime());
}
}
}

View File

@@ -1,121 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.CollisionDetectionComponent;
import ve.ucv.ciens.ccg.nxtar.components.CollisionModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.managers.GroupManager;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.collision.BoundingBox;
public class CollisionDetectionSystem extends EntityProcessingSystem {
public static final String COLLIDABLE_OBJECTS_GROUP = "COLLIDABLE";
@Mapper ComponentMapper<CollisionModelComponent> collisionModelMapper;
@Mapper ComponentMapper<CollisionDetectionComponent> collisionDetectionMapper;
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
private GroupManager groupManager;
private BoundingBox colBB;
private BoundingBox targetBB;
private boolean collisionsEnabled;
@SuppressWarnings("unchecked")
public CollisionDetectionSystem(){
super(Aspect.getAspectForAll(CollisionModelComponent.class, CollisionDetectionComponent.class).exclude(MarkerCodeComponent.class));
colBB = new BoundingBox();
targetBB = new BoundingBox();
collisionsEnabled = true;
}
@Override
protected void process(Entity e) {
VisibilityComponent visibility;
CollisionModelComponent collision;
CollisionModelComponent target;
CollisionDetectionComponent onCollision;
CollisionDetectionComponent onCollisionTarget;
ImmutableBag<Entity> collidables;
if(!collisionsEnabled)
return;
// Get this entity's known necessary components.
collision = collisionModelMapper.get(e);
onCollision = collisionDetectionMapper.get(e);
// Get all other entities this entity can collide with.
groupManager = this.world.getManager(GroupManager.class);
collidables = groupManager.getEntities(COLLIDABLE_OBJECTS_GROUP);
for(int i = 0; i < collidables.size(); ++i){
// Try to get the necessary components for the collidable entity.
target = collisionModelMapper.getSafe(collidables.get(i));
visibility = visibilityMapper.getSafe(collidables.get(i));
onCollisionTarget = collisionDetectionMapper.getSafe(collidables.get(i));
// If any of the needed components does not exist then proceed to the next entity.
if(target == null || visibility == null || onCollisionTarget == null) continue;
// Id the target is visible then examine the collision. Else there is no collision possible.
if(visibility.visible){
// Get the bounding box for both entities.
collision.instance.calculateBoundingBox(colBB);
target.instance.calculateBoundingBox(targetBB);
// Apply the model matrix to the bounding boxes.
colBB.mul(collision.instance.transform);
targetBB.mul(target.instance.transform);
// If the bounding boxes intersect then there is a collision.
if(colBB.intersects(targetBB) || targetBB.intersects(colBB)){
Gdx.app.log("TAG", "Collision hit.");
onCollision.colliding = true;
onCollisionTarget.colliding = true;
break;
}else{
Gdx.app.log("TAG", "Collision miss.");
onCollision.colliding = false;
onCollisionTarget.colliding = false;
}
}else{
onCollision.colliding = false;
onCollisionTarget.colliding = false;
}
}
}
public boolean isCollisionDetectionEnabled(){
return collisionsEnabled;
}
public void enableCollisions(){
this.collisionsEnabled = true;
}
public void disableCollisions(){
this.collisionsEnabled = false;
}
}

View File

@@ -1,62 +0,0 @@
package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.components.FadeEffectComponent;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.Disposable;
public class FadeEffectRenderingSystem extends EntityProcessingSystem implements Disposable{
@Mapper ComponentMapper<FadeEffectComponent> fadeMapper;
private SpriteBatch batch;
private Texture fadeTexture;
private OrthographicCamera camera;
@SuppressWarnings("unchecked")
public FadeEffectRenderingSystem(){
super(Aspect.getAspectForAll(FadeEffectComponent.class));
this.batch = new SpriteBatch();
this.batch.enableBlending();
this.camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Pixmap pixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Format.RGBA4444);
pixmap.setColor(1, 1, 1, 1);
pixmap.fill();
fadeTexture = new Texture(pixmap);
pixmap.dispose();
}
@Override
public void dispose(){
this.fadeTexture.dispose();
this.batch.dispose();
}
@Override
protected void process(Entity e) {
float r, g, b;
FadeEffectComponent fade = fadeMapper.get(e);
r = fade.color.r;
g = fade.color.g;
b = fade.color.b;
this.batch.setProjectionMatrix(this.camera.combined);
this.batch.begin();{
this.batch.setColor(r, g, b, fade.getFloatValue());
this.batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
this.batch.setColor(1, 1, 1, 1);
}this.batch.end();
}
}

View File

@@ -1,103 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.CollisionModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.RenderModelComponent;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.math.Matrix4;
public class GeometrySystem extends EntityProcessingSystem {
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<RenderModelComponent> renderModelMapper;
@Mapper ComponentMapper<CollisionModelComponent> colModelMapper;
/**
* <p>A matrix representing 3D translations.</p>
*/
private Matrix4 translationMatrix;
/**
* <p>A matrix representing 3D rotations.</p>
*/
private Matrix4 rotationMatrix;
/**
* <p>A matrix representing 3D scalings.</p>
*/
private Matrix4 scalingMatrix;
@SuppressWarnings("unchecked")
public GeometrySystem(){
super(Aspect.getAspectForAll(GeometryComponent.class).one(RenderModelComponent.class, CollisionModelComponent.class));
translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f);
rotationMatrix = new Matrix4().idt();
scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f);
}
@Override
protected void process(Entity e) {
GeometryComponent geometry;
RenderModelComponent renderModel;
CollisionModelComponent colModel;
geometry = geometryMapper.get(e);
renderModel = renderModelMapper.getSafe(e);
colModel = colModelMapper.getSafe(e);
if(renderModel != null)
applyWorldTransform(renderModel.instance, geometry);
if(colModel != null)
applyWorldTransform(colModel.instance, geometry);
}
private void applyWorldTransform(ModelInstance model, GeometryComponent geometry){
translationMatrix.setToTranslation(geometry.position);
rotationMatrix.val[Matrix4.M00] = geometry.rotation.val[0];
rotationMatrix.val[Matrix4.M10] = geometry.rotation.val[1];
rotationMatrix.val[Matrix4.M20] = geometry.rotation.val[2];
rotationMatrix.val[Matrix4.M30] = 0;
rotationMatrix.val[Matrix4.M01] = geometry.rotation.val[3];
rotationMatrix.val[Matrix4.M11] = geometry.rotation.val[4];
rotationMatrix.val[Matrix4.M21] = geometry.rotation.val[5];
rotationMatrix.val[Matrix4.M31] = 0;
rotationMatrix.val[Matrix4.M02] = geometry.rotation.val[6];
rotationMatrix.val[Matrix4.M12] = geometry.rotation.val[7];
rotationMatrix.val[Matrix4.M22] = geometry.rotation.val[8];
rotationMatrix.val[Matrix4.M32] = 0;
rotationMatrix.val[Matrix4.M03] = 0;
rotationMatrix.val[Matrix4.M13] = 0;
rotationMatrix.val[Matrix4.M23] = 0;
rotationMatrix.val[Matrix4.M33] = 1;
scalingMatrix.setToScaling(geometry.scaling);
model.transform.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix);
model.calculateTransforms();
}
}

View File

@@ -17,7 +17,6 @@ package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
@@ -26,17 +25,20 @@ import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
public class MarkerPositioningSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
private static final String TAG = "MARKER_POSITIONING_SYSTEM";
private static final String CLASS_NAME = MarkerPositioningSystem.class.getSimpleName();
private MarkerData markers;
@SuppressWarnings("unchecked")
public MarkerPositioningSystem(){
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, VisibilityComponent.class));
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class));
markers = null;
}
@@ -49,26 +51,28 @@ public class MarkerPositioningSystem extends EntityProcessingSystem {
protected void process(Entity e) {
MarkerCodeComponent marker;
GeometryComponent geometry;
VisibilityComponent visibility;
if(markers == null)
return;
marker = markerMapper.get(e);
geometry = geometryMapper.get(e);
visibility = visibilityMapper.get(e);
Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components.");
marker = markerMapper.get(e);
geometry = geometryMapper.get(e);
Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing markers.");
for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){
if(markers.markerCodes[i] != 1){
if(markers.markerCodes[i] == marker.code){
Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing marker code " + Integer.toString(markers.markerCodes[i]) + ".");
geometry.position.set(markers.translationVectors[i]);
geometry.rotation.set(markers.rotationMatrices[i]);
visibility.visible = true;
break;
}else{
visibility.visible = false;
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + ".");
}
}
markers = null;
}
}

View File

@@ -1,82 +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.systems;
import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent;
import ve.ucv.ciens.ccg.nxtar.components.RenderModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.components.VisibilityComponent;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.math.Matrix4;
public class MarkerRenderingSystem extends EntityProcessingSystem {
// @Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<RenderModelComponent> modelMapper;
@Mapper ComponentMapper<EnvironmentComponent> environmentMapper;
@Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<VisibilityComponent> visibiltyMapper;
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<MeshComponent> meshMapper;
private PerspectiveCamera camera;
private ModelBatch batch;
private static final String TAG = "MARKER_RENDERING_SYSTEM";
private static final String CLASS_NAME = MarkerRenderingSystem.class.getSimpleName();
/**
* <p>A matrix representing 3D translations.</p>
*/
private Matrix4 translationMatrix;
/**
* <p>A matrix representing 3D rotations.</p>
*/
private Matrix4 rotationMatrix;
/**
* <p>A matrix representing 3D scalings.</p>
*/
private Matrix4 scalingMatrix;
/**
* <p>The total transformation to be applied to an entity.</p>
*/
private Matrix4 combinedTransformationMatrix;
MarkerData markers;
@SuppressWarnings("unchecked")
public MarkerRenderingSystem(ModelBatch batch){
super(Aspect.getAspectForAll(ShaderComponent.class, EnvironmentComponent.class, RenderModelComponent.class, VisibilityComponent.class));
public MarkerRenderingSystem(){
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, ShaderComponent.class, MeshComponent.class));
camera = null;
this.batch = batch;
markers = null;
translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f);
rotationMatrix = new Matrix4().idt();
scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f);
combinedTransformationMatrix = new Matrix4();
}
public void begin(PerspectiveCamera camera) throws RuntimeException{
if(this.camera != null)
throw new RuntimeException("Begin called twice without calling end.");
this.camera = camera;
batch.begin(camera);
}
public void end(){
batch.end();
camera = null;
public void setMarkerData(MarkerData markers){
this.markers = markers;
}
@Override
protected void process(Entity e) {
EnvironmentComponent environment;
RenderModelComponent model;
ShaderComponent shader;
VisibilityComponent visibility;
MarkerCodeComponent marker;
GeometryComponent geometry;
ShaderComponent shaderComp;
MeshComponent meshComp;
if(camera == null)
if(markers == null)
return;
model = modelMapper.get(e);
environment = environmentMapper.get(e);
shader = shaderMapper.get(e);
visibility = visibiltyMapper.get(e);
Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components.");
marker = markerMapper.get(e);
geometry = geometryMapper.get(e);
shaderComp = shaderMapper.get(e);
meshComp = meshMapper.get(e);
if(visibility.visible){
// Render the marker;
batch.render(model.instance, environment.environment, shader.shader);
Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing markers.");
for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){
if(markers.markerCodes[i] != 1){
if(markers.markerCodes[i] == marker.code){
Gdx.app.log(TAG, CLASS_NAME + ".process(): Rendering marker code " + Integer.toString(markers.markerCodes[i]) + ".");
// Set the geometric transformations.
translationMatrix.setToTranslation(geometry.position);
rotationMatrix.val[0] = geometry.rotation.val[0];
rotationMatrix.val[1] = geometry.rotation.val[1];
rotationMatrix.val[2] = geometry.rotation.val[2];
rotationMatrix.val[3] = 0;
rotationMatrix.val[4] = geometry.rotation.val[3];
rotationMatrix.val[5] = geometry.rotation.val[4];
rotationMatrix.val[6] = geometry.rotation.val[5];
rotationMatrix.val[7] = 0;
rotationMatrix.val[8] = geometry.rotation.val[6];
rotationMatrix.val[9] = geometry.rotation.val[7];
rotationMatrix.val[10] = geometry.rotation.val[8];
rotationMatrix.val[11] = 0;
rotationMatrix.val[12] = 0;
rotationMatrix.val[13] = 0;
rotationMatrix.val[14] = 0;
rotationMatrix.val[15] = 1;
scalingMatrix.setToScaling(geometry.scaling);
combinedTransformationMatrix.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix);
RenderParameters.setTransformationMatrix(combinedTransformationMatrix);
// Render the marker;
shaderComp.shader.getShaderProgram().begin();{
shaderComp.shader.setUniforms();
meshComp.model.render(shaderComp.shader.getShaderProgram(), GL20.GL_TRIANGLES);
}shaderComp.shader.getShaderProgram().end();
break;
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + ".");
}
}
markers = null;
}
}

View File

@@ -0,0 +1,114 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.graphics.LightSource;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
/**
* <p>Entity processing system in charge of rendering 3D objects using OpenGL. The
* entities to be rendered must have a geometry, shader and mesh component associated.</p>
*/
public class ObjectRenderingSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<MeshComponent> modelMapper;
private static final Vector3 LIGHT_POSITION = new Vector3(2.0f, 2.0f, 4.0f);
private static final Color AMBIENT_COLOR = new Color(0.0f, 0.1f, 0.2f, 1.0f);
private static final Color DIFFUSE_COLOR = new Color(1.0f, 1.0f, 1.0f, 1.0f);
private static final Color SPECULAR_COLOR = new Color(1.0f, 0.8f, 0.0f, 1.0f);
private static final float SHINYNESS = 50.0f;
/**
* <p>A matrix representing 3D translations.</p>
*/
private Matrix4 translationMatrix;
/**
* <p>A matrix representing 3D rotations.</p>
*/
private Matrix4 rotationMatrix;
/**
* <p>A matrix representing 3D scalings.</p>
*/
private Matrix4 scalingMatrix;
/**
* <p>The total transformation to be applied to an entity.</p>
*/
private Matrix4 combinedTransformationMatrix;
@SuppressWarnings("unchecked")
public ObjectRenderingSystem() {
super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, MeshComponent.class).exclude(MarkerCodeComponent.class));
RenderParameters.setLightSource1(new LightSource(LIGHT_POSITION, AMBIENT_COLOR, DIFFUSE_COLOR, SPECULAR_COLOR, SHINYNESS));
translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f);
rotationMatrix = new Matrix4().idt();
scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f);
combinedTransformationMatrix = new Matrix4();
}
/**
* <p>Renders the entity passed by parameter, calculating it's corresponding geometric
* transformation and setting and calling it's associated shader program.</p>
*
* @param e The entity to be processed.
*/
@Override
protected void process(Entity e) {
GeometryComponent geometryComponent;
ShaderComponent shaderComponent;
MeshComponent meshComponent;
// Get the necessary components.
geometryComponent = geometryMapper.get(e);
meshComponent = modelMapper.get(e);
shaderComponent = shaderMapper.get(e);
// Calculate the geometric transformation for this entity.
translationMatrix.setToTranslation(geometryComponent.position);
rotationMatrix.set(geometryComponent.rotation);
scalingMatrix.setToScaling(geometryComponent.scaling);
combinedTransformationMatrix.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix);
// Set up the global rendering parameters for this frame.
RenderParameters.setTransformationMatrix(combinedTransformationMatrix);
// Render this entity.
shaderComponent.shader.getShaderProgram().begin();{
shaderComponent.shader.setUniforms();
meshComponent.model.render(shaderComponent.shader.getShaderProgram(), GL20.GL_TRIANGLES);
}shaderComponent.shader.getShaderProgram().end();
}
}

View File

@@ -1,51 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.components.PlayerComponentBase;
import ve.ucv.ciens.ccg.nxtar.scenarios.ScenarioGlobals;
import ve.ucv.ciens.ccg.nxtar.scenarios.SummaryBase;
import com.artemis.Aspect;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.utils.Disposable;
public abstract class PlayerSystemBase extends EntityProcessingSystem implements Disposable{
protected NxtARCore core;
@SuppressWarnings("unchecked")
public PlayerSystemBase(Class<? extends PlayerComponentBase> component){
super(Aspect.getAspectForAll(component));
}
public abstract SummaryBase getPlayerSummary();
public final void setCore(NxtARCore core) throws IllegalArgumentException{
if(core == null)
throw new IllegalArgumentException("Core is null.");
this.core = core;
}
protected final void finishGame(boolean victory) throws IllegalStateException{
if(core == null)
throw new IllegalStateException("Core is null.");
ScenarioGlobals.getEntityCreator().resetAllEntities();
core.nextState = NxtARCore.game_states_t.SCENARIO_END_SUMMARY;
}
}

View File

@@ -1,179 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.AutomaticMovementComponent;
import ve.ucv.ciens.ccg.nxtar.components.CollisionDetectionComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.input.GamepadUserInput;
import ve.ucv.ciens.ccg.nxtar.input.KeyboardUserInput;
import ve.ucv.ciens.ccg.nxtar.input.TouchUserInput;
import ve.ucv.ciens.ccg.nxtar.input.UserInput;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.math.Vector3;
public class RobotArmPositioningSystem extends EntityProcessingSystem {
private static final String TAG = "ROBOT_ARM_POSITIONING_SYSTEM";
private static final String CLASS_NAME = RobotArmPositioningSystem.class.getSimpleName();
private static final float INTERPOLATION_STEP = 0.05f;
private static final float STEP_SIZE = 0.05f;
public static final float MAX_Z = -4.5f;
public static final float MIN_Z = -1.0f;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<AutomaticMovementComponent> autoMapper;
@Mapper ComponentMapper<CollisionDetectionComponent> collisionMapper;
private UserInput input;
@SuppressWarnings("unchecked")
public RobotArmPositioningSystem(){
super(Aspect.getAspectForAll(GeometryComponent.class, AutomaticMovementComponent.class, CollisionDetectionComponent.class).exclude(MarkerCodeComponent.class));
}
public void setUserInput(UserInput input){
this.input = input;
}
@Override
protected void process(Entity e) throws ClassCastException{
Vector3 endPoint;
GamepadUserInput tempGP;
KeyboardUserInput tempKey;
GeometryComponent geometry = geometryMapper.get(e);
AutomaticMovementComponent auto = autoMapper.get(e);
CollisionDetectionComponent collision = collisionMapper.get(e);
if(input == null){
if(auto.moving) autoMove(geometry, auto, collision);
else return;
}else{
if(input instanceof TouchUserInput){
if(!auto.moving){
endPoint = ((TouchUserInput) input).userTouchEndPoint;
endPoint.set(geometry.position.x, geometry.position.y, MAX_Z);
auto.startPoint.set(geometry.position);
auto.endPoint.set(endPoint);
auto.moving = true;
auto.forward = true;
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;
if(!auto.moving){
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)
input = null;
else
input = (UserInput)tempGP;
}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);
input = null;
}
}else if(input instanceof KeyboardUserInput){
tempKey = (KeyboardUserInput) input;
if(!auto.moving){
if(!tempKey.keySpace){
geometry.position.x += tempKey.keyUp ? STEP_SIZE : 0.0f;
geometry.position.x -= tempKey.keyDown ? STEP_SIZE : 0.0f;
geometry.position.y -= tempKey.keyLeft ? STEP_SIZE : 0.0f;
geometry.position.y += tempKey.keyRight ? STEP_SIZE : 0.0f;
if(!tempKey.keyUp && !tempKey.keyUp && !tempKey.keyUp && !tempKey.keyUp)
input = null;
else
input = (UserInput)tempKey;
}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);
input = null;
}
}else
throw new ClassCastException("Input is not a valid UserInput instance.");
}
}
private void autoMove(GeometryComponent geometry, AutomaticMovementComponent auto, CollisionDetectionComponent collision){
float step;
if(auto.moving){
if(auto.forward)
step = INTERPOLATION_STEP;
else
step = -INTERPOLATION_STEP;
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Step = " + Float.toString(step));
auto.distance += step;
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Step = " + Float.toString(auto.distance));
geometry.position.x = (auto.startPoint.x * (1.0f - auto.distance)) + (auto.endPoint.x * auto.distance);
geometry.position.y = (auto.startPoint.y * (1.0f - auto.distance)) + (auto.endPoint.y * auto.distance);
geometry.position.z = (auto.startPoint.z * (1.0f - auto.distance)) + (auto.endPoint.z * auto.distance);
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Current position: " + Utils.vector2String(geometry.position));
if(auto.distance <= 0.0f || geometry.position.z >= MIN_Z){
geometry.position.x = auto.startPoint.x;
geometry.position.y = auto.startPoint.y;
geometry.position.z = MIN_Z;
auto.forward = true;
auto.moving = false;
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Going forward now.");
}else if(auto.distance >= 1.0f || collision.colliding){
auto.forward = false;
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Going backwards now.");
}
}else return;
}
}

View File

@@ -1,115 +0,0 @@
/*
* 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.systems;
import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.RenderModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Disposable;
/**
* <p>Entity processing system in charge of rendering 3D objects using OpenGL. The
* entities to be rendered must have a geometry, shader and mesh component associated.</p>
*/
public class RobotArmRenderingSystem extends EntityProcessingSystem implements Disposable{
@Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<RenderModelComponent> modelMapper;
@Mapper ComponentMapper<EnvironmentComponent> environmentMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
private PerspectiveCamera camera;
private ModelBatch batch;
private Model lineModel;
private ModelInstance lineInstance;
private Vector3 temp;
@SuppressWarnings("unchecked")
public RobotArmRenderingSystem(ModelBatch batch) {
super(Aspect.getAspectForAll(ShaderComponent.class, RenderModelComponent.class, EnvironmentComponent.class).exclude(MarkerCodeComponent.class));
camera = null;
this.batch = batch;
// MeshBuilder builder = new MeshBuilder();
// builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 4, "a_position"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_LINES);{
// builder.line(new Vector3(0.0f, 0.0f, RobotArmPositioningSystem.MIN_Z), Color.YELLOW, new Vector3(0.0f, 0.0f, RobotArmPositioningSystem.MAX_Z), Color.YELLOW);
// }lineMesh = builder.end();
// lineModel = ModelBuilder.createFromMesh(lineMesh, GL20.GL_LINES, new Material(new ColorAttribute(ColorAttribute.Diffuse, Color.YELLOW)));
// lineModel = new ModelBuilder().createArrow(new Vector3(0.0f, 0.0f, RobotArmPositioningSystem.MIN_Z), new Vector3(0.0f, 0.0f, RobotArmPositioningSystem.MAX_Z), new Material(new ColorAttribute(ColorAttribute.Diffuse, Color.YELLOW)), Usage.Position | Usage.Color | Usage.Normal);
lineModel = new ModelBuilder().createBox(0.01f, 0.01f, 3.5f, new Material(new ColorAttribute(ColorAttribute.Diffuse, Color.YELLOW)), Usage.Position | Usage.Color | Usage.Normal);
lineInstance = new ModelInstance(lineModel);
temp = new Vector3();
}
public void begin(PerspectiveCamera camera) throws RuntimeException{
if(this.camera != null)
throw new RuntimeException("Begin called twice without calling end.");
this.camera = camera;
batch.begin(camera);
}
public void end(){
batch.end();
camera = null;
}
@Override
protected void process(Entity e) {
EnvironmentComponent environment;
ShaderComponent shaderComponent;
RenderModelComponent renderModelComponent;
GeometryComponent geometry;
// Get the necessary components.
renderModelComponent = modelMapper.get(e);
shaderComponent = shaderMapper.get(e);
environment = environmentMapper.get(e);
geometry = geometryMapper.getSafe(e);
if(geometry != null){
temp.set(geometry.position.x, geometry.position.y, -2.5f);
lineInstance.transform.idt().setToTranslation(temp);
}
// Render this entity.
batch.render(renderModelComponent.instance, environment.environment, shaderComponent.shader);
batch.render(lineInstance, environment.environment, shaderComponent.shader);
}
@Override
public void dispose() {
if(lineModel != null)
lineModel.dispose();
}
}

View File

@@ -28,14 +28,13 @@ public abstract class ProjectConstants{
public static final int EXIT_SUCCESS = 0;
public static final int EXIT_FAILURE = 1;
public static final boolean DEBUG = false;
public static final boolean DEBUG = true;
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

@@ -1,87 +0,0 @@
/*
* 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.utils;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Peripheral;
import com.badlogic.gdx.math.Vector3;
/**
* Assorted common auxiliary functions.
*/
public abstract class Utils{
private static final float MIN_PITCH = -80.0f;
private static final float MAX_PITCH = 5.0f;
private static final float MIN_AZIMUTH = -155.0f;
private static final float MAX_AZIMUTH = -40.0f;
/**
* <p>Converts a libGDX {@link Vector3} to a String representation form easy logging.</p>
*
* @param v The vector to convert.
* @return A string representation of the form "(v.x, v.y, v.z)".
*/
public static String vector2String(Vector3 v){
return "(" + Float.toString(v.x) + ", " + Float.toString(v.y) + ", " + Float.toString(v.z) + ")";
}
/**
* @return The width of the screen accounting for screen overscan.
*/
public static int getScreenWidthWithOverscan(){
return (int)(Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN);
}
/**
* @return The height of the screen accounting for screen overscan.
*/
public static int getScreenHeightWithOverscan(){
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 = true;
float azimuth, pitch;
if(deviceHasOrientationSensors()){
azimuth = Gdx.input.getAzimuth();
pitch = Gdx.input.getPitch();
if(pitch < MIN_PITCH || pitch > MAX_PITCH)
rollValid = false;
if(rollValid && (azimuth < MIN_AZIMUTH || azimuth > MAX_AZIMUTH))
rollValid = false;
}else
rollValid = false;
return rollValid;
}
}