Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
b2cac2f40d | |||
53ae001e59 | |||
a9285a684f | |||
81d8a81b7e | |||
5a8391aa28 | |||
94c2bd6850 | |||
3288e3cb6b | |||
83e327545c | |||
77aec83dbb | |||
4d006a3461 | |||
6e30e6b56b | |||
99236420d1 | |||
6a392856ee | |||
83199df36d | |||
a247d24770 | |||
8bd799f146 | |||
29c4bea104 | |||
fd197211b5 | |||
7f20a09eb9 | |||
6c63ebf907 | |||
95bb97536c | |||
3f522da485 | |||
36eea36c15 | |||
8abf594c8a | |||
aa5871b49a | |||
d4edcf4909 | |||
4cba697f57 | |||
be5ae2955e | |||
2b14a080b4 | |||
fbb03f884e | |||
a798cce715 | |||
6ecb373b11 | |||
e65da3234b | |||
a614841664 | |||
eb8206668f | |||
fa6950d5c9 | |||
5e66273396 | |||
686f263b0d | |||
5ef7928706 | |||
169d0e7c43 | |||
9a67df8f8a | |||
76a6d8485b | |||
653adc91a7 | |||
a1891f53d2 | |||
a942b0ebd1 | |||
e6085e7a79 | |||
3c65f52e9e | |||
0df8b37ddd | |||
87295031dc | |||
a9fa76cb68 | |||
fbb25ead08 | |||
82e95ed0f7 | |||
b7367427f6 | |||
e6ea6ab4a1 | |||
167b5d644b | |||
e82d49f1f1 | |||
6b54b1364f | |||
de64cd972b | |||
90427419e0 | |||
271b7d003a | |||
1146a260b6 | |||
d8922182e0 | |||
e976a17de0 | |||
11ebf2b96e | |||
139bb62067 | |||
e93d227b62 | |||
06d74a6474 | |||
d481df0f96 | |||
1e2de5ee55 | |||
a37ff0fba5 | |||
ebb943925f |
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
NxtAR: A generic software architecture for Augmented Reality based mobile robot control.
|
||||
========================================================================================
|
||||
|
||||
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/
|
Binary file not shown.
BIN
libs/gdx.jar
BIN
libs/gdx.jar
Binary file not shown.
@@ -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};
|
||||
public enum motor_t {NONE, MOTOR_A, MOTOR_B, MOTOR_C, MOTOR_AC, RECENTER, ROTATE_90};
|
||||
|
||||
private motor_t motor;
|
||||
private byte power;
|
||||
|
@@ -15,20 +15,26 @@
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.MulticastEnabler;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.NetworkConnectionListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.Toaster;
|
||||
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.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.PauseState;
|
||||
import ve.ucv.ciens.ccg.nxtar.states.ScenarioEndSummaryState;
|
||||
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;
|
||||
@@ -38,33 +44,41 @@ import com.badlogic.gdx.Game;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.controllers.Controllers;
|
||||
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
|
||||
|
||||
/**
|
||||
* <p>Core of the application.</p>
|
||||
*
|
||||
* <p>This class has three basic resposibilities:</p>
|
||||
* <p>This class has three basic responsibilities:</p>
|
||||
* <ul>
|
||||
* <li> Handling the main game loop.</li>
|
||||
* <li> Starting and destroying the networking threads.</li>
|
||||
* <li> Rendering debug information.</li>
|
||||
* </ul>
|
||||
* @author Miguel Angel Astor Romero
|
||||
*/
|
||||
public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
public class NxtARCore extends Game implements ApplicationEventsListener{
|
||||
/**
|
||||
* Tag used for logging.
|
||||
*/
|
||||
private static final String TAG = "NXTAR_CORE_MAIN";
|
||||
|
||||
/**
|
||||
* Class name used for logging.
|
||||
*/
|
||||
private static final String CLASS_NAME = NxtARCore.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Valid game states.
|
||||
*/
|
||||
public enum game_states_t {
|
||||
MAIN_MENU(0), IN_GAME(1), PAUSED(2);
|
||||
MAIN_MENU(0), IN_GAME(1), CALIBRATION(2), AUTOMATIC_ACTION(3), AUTOMATIC_ACTION_SUMMARY(4), SCENARIO_END_SUMMARY(5), HINTS(6);
|
||||
|
||||
private int value;
|
||||
|
||||
@@ -75,11 +89,17 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
public int getValue(){
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static int getNumStates(){
|
||||
return 7;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The current application state.
|
||||
*/
|
||||
private game_states_t currState;
|
||||
|
||||
/**
|
||||
* <p>The state to change to.</p>
|
||||
* <p> Usually null. A state change is scheduled by setting this field to a {@link game_states_t} value.</p>
|
||||
@@ -87,30 +107,98 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
public game_states_t nextState;
|
||||
|
||||
// Screens.
|
||||
/**
|
||||
* <p>The application states.</p>
|
||||
*/
|
||||
private BaseState[] states;
|
||||
|
||||
// Assorted fields.
|
||||
/**
|
||||
* <p>Global sprite batch used for rendering trough the application.</p>
|
||||
*/
|
||||
public SpriteBatch batch;
|
||||
public CVProcessor cvProc;
|
||||
private Toaster toaster;
|
||||
|
||||
/**
|
||||
* <p>The OpenCV wrapper.</p>
|
||||
*/
|
||||
public ImageProcessor cvProc;
|
||||
|
||||
/**
|
||||
* <p>Wrapper around the Operating System methods.</p>
|
||||
*/
|
||||
private ActionResolver actionResolver;
|
||||
|
||||
// Networking related fields.
|
||||
/**
|
||||
* <p>The number of connections successfully established with the NxtAR-cam application.</p>
|
||||
*/
|
||||
private int connections;
|
||||
private MulticastEnabler mcastEnabler;
|
||||
|
||||
/**
|
||||
* <p>Worker thread used to broadcast this server over the network.</p>
|
||||
*/
|
||||
private ServiceDiscoveryThread serviceDiscoveryThread;
|
||||
|
||||
/**
|
||||
* <p>Worker thread used to receive video frames over UDP.<p>
|
||||
*/
|
||||
private VideoStreamingThread videoThread;
|
||||
|
||||
/**
|
||||
* <p>Worker thread used to send control commands to the NxtAR-cam application.
|
||||
*/
|
||||
private RobotControlThread robotThread;
|
||||
|
||||
/**
|
||||
* <p>Worker thread used to receive sensor data from the NxtAR-cam application.</p>
|
||||
*/
|
||||
private SensorReportThread sensorThread;
|
||||
|
||||
// Overlays.
|
||||
/**
|
||||
* <p>Camera used to render the debugging overlay.</p>
|
||||
*/
|
||||
private OrthographicCamera pixelPerfectCamera;
|
||||
private float fontX;
|
||||
private float fontY;
|
||||
|
||||
/**
|
||||
* <p>The base x coordinate for rendering the debugging overlay.</p>
|
||||
*/
|
||||
private float overlayX;
|
||||
|
||||
/**
|
||||
* <p>The base y coordinate for rendering the debugging overlay.</p>
|
||||
*/
|
||||
private float overlayY;
|
||||
|
||||
/**
|
||||
* <p>The font used to render the debugging overlay.</p>
|
||||
*/
|
||||
private BitmapFont font;
|
||||
|
||||
// Fade in/out effect fields.
|
||||
/**
|
||||
* <p>The graphic used to render the fading effect.</p>
|
||||
*/
|
||||
private Texture fadeTexture;
|
||||
|
||||
/**
|
||||
* <p>The interpolation value for the fading effect.</p>
|
||||
*/
|
||||
private MutableFloat alpha;
|
||||
|
||||
/**
|
||||
* <p>The fade out interpolator.</p>
|
||||
*/
|
||||
private Tween fadeOut;
|
||||
|
||||
/**
|
||||
* <p>The fade in interpolator.</p>
|
||||
*/
|
||||
private Tween fadeIn;
|
||||
|
||||
/**
|
||||
* <p>Flag used to indicate if a fading effect is active.</p>
|
||||
*/
|
||||
private boolean fading;
|
||||
|
||||
/**
|
||||
@@ -118,68 +206,121 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
*/
|
||||
public NxtARCore(Application concreteApp){
|
||||
super();
|
||||
|
||||
connections = 0;
|
||||
|
||||
// Check if the concrete application implements all required interfaces.
|
||||
try{
|
||||
this.toaster = (Toaster)concreteApp;
|
||||
this.actionResolver = (ActionResolver)concreteApp;
|
||||
}catch(ClassCastException cc){
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the Toaster interface. Toasting disabled.");
|
||||
this.toaster = null;
|
||||
this.actionResolver = null;
|
||||
}
|
||||
|
||||
try{
|
||||
this.mcastEnabler = (MulticastEnabler)concreteApp;
|
||||
}catch(ClassCastException cc){
|
||||
Gdx.app.error(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement MulticastEnabler. Quitting.");
|
||||
Gdx.app.exit();
|
||||
}
|
||||
|
||||
try{
|
||||
this.cvProc = (CVProcessor)concreteApp;
|
||||
this.cvProc = (ImageProcessor)concreteApp;
|
||||
}catch(ClassCastException cc){
|
||||
Gdx.app.error(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the CVProcessor interface. Quitting.");
|
||||
Gdx.app.exit();
|
||||
}
|
||||
}
|
||||
|
||||
public void create(){
|
||||
// Create the state objects.
|
||||
states = new BaseState[3];
|
||||
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);
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; GAME SUPERCLASS METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
/**
|
||||
* <p>Initialize the member fields and launch the networking threads. Also creates and
|
||||
* 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;
|
||||
}
|
||||
|
||||
// Register controller listeners.
|
||||
for(BaseState state : states){
|
||||
Controllers.addListener(state);
|
||||
}
|
||||
|
||||
// Set up fields.
|
||||
batch = new SpriteBatch();
|
||||
// Set up the overlay font.
|
||||
overlayX = -(Utils.getScreenWidthWithOverscan() / 2) + 10;
|
||||
overlayY = (Utils.getScreenHeightWithOverscan() / 2) - 10;
|
||||
|
||||
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
|
||||
if(ProjectConstants.DEBUG){
|
||||
// Set up the overlay font.
|
||||
fontX = -((Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN) / 2) + 10;
|
||||
fontY = ((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);
|
||||
}
|
||||
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.
|
||||
mcastEnabler.enableMulticast();
|
||||
actionResolver.enableMulticast();
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".create() :: Creating network threads");
|
||||
serviceDiscoveryThread = ServiceDiscoveryThread.getInstance();
|
||||
videoThread = VideoStreamingThread.getInstance();
|
||||
robotThread = RobotControlThread.getInstance();
|
||||
sensorThread = SensorReportThread.getInstance();
|
||||
|
||||
// Launch networking threads.
|
||||
serviceDiscoveryThread.start();
|
||||
|
||||
videoThread.start();
|
||||
@@ -189,58 +330,72 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
robotThread.addNetworkConnectionListener(this);
|
||||
robotThread.start();
|
||||
|
||||
sensorThread.addNetworkConnectionListener(this);
|
||||
sensorThread.start();
|
||||
|
||||
// Set the current and next states.
|
||||
currState = game_states_t.MAIN_MENU;
|
||||
nextState = null;
|
||||
this.setScreen(states[currState.getValue()]);
|
||||
states[currState.getValue()].onStateSet();
|
||||
|
||||
// Prepare the fadeToBlack sprite;
|
||||
// Prepare the fading effect.
|
||||
Pixmap pixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Format.RGBA4444);
|
||||
pixmap.setColor(0, 0, 0, 1);
|
||||
pixmap.fill();
|
||||
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()]);
|
||||
Controllers.addListener(states[currState.getValue()]);
|
||||
|
||||
// Anything else.
|
||||
//Gdx.app.setLogLevel(Application.LOG_INFO);
|
||||
//Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||
Gdx.app.setLogLevel(Application.LOG_NONE);
|
||||
// Set log level
|
||||
if(ProjectConstants.DEBUG){
|
||||
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||
}else{
|
||||
Gdx.app.setLogLevel(Application.LOG_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Update and render the currently enabled application state. This method
|
||||
* also handles state switching, rendering state transitions and global overlays.</p>
|
||||
*/
|
||||
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();
|
||||
|
||||
if(!fadeOut.isStarted()){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".onRender() :: Starting fade out.");
|
||||
// Start the fade out effect.
|
||||
fadeOut.start();
|
||||
fading = true;
|
||||
}else{
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".onRender() :: Updating fade out.");
|
||||
// Update the fade out effect.
|
||||
fadeOut.update(Gdx.graphics.getDeltaTime());
|
||||
|
||||
// When the fade out effect finishes, change to the requested state
|
||||
// and launh the fade in effect.
|
||||
if(fadeOut.isFinished()){
|
||||
// Change to the requested state.
|
||||
currState = nextState;
|
||||
nextState = null;
|
||||
|
||||
states[currState.getValue()].onStateSet();
|
||||
|
||||
setScreen(states[currState.getValue()]);
|
||||
|
||||
// Reset the fade out effect and launch the fade in.
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".onRender() :: Freeing fade out.");
|
||||
fadeOut.free();
|
||||
fadeOut = Tween.to(alpha, 0, 0.5f).target(1.0f).ease(TweenEquations.easeInQuint);
|
||||
@@ -249,16 +404,20 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a fade in effect in progress.
|
||||
if(fadeIn.isStarted()){
|
||||
if(!fadeIn.isFinished()){
|
||||
// Update it until finished.
|
||||
fadeIn.update(Gdx.graphics.getDeltaTime());
|
||||
}else{
|
||||
// Stop and reset it when done.
|
||||
fading = false;
|
||||
fadeIn.free();
|
||||
fadeIn = Tween.to(alpha, 0, 0.5f).target(0.0f).ease(TweenEquations.easeInQuint);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the fading sprite with alpha blending.
|
||||
if(fading){
|
||||
batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||
batch.begin();{
|
||||
@@ -268,63 +427,116 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
|
||||
}batch.end();
|
||||
}
|
||||
|
||||
// Render the debug overlay.
|
||||
if(ProjectConstants.DEBUG){
|
||||
batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||
batch.begin();{
|
||||
// Draw the FPS overlay.
|
||||
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), fontX, fontY);
|
||||
font.draw(batch, String.format("Total stream FPS: %d", videoThread.getFps()), fontX, fontY - font.getCapHeight() - 5);
|
||||
font.draw(batch, String.format("Lost stream FPS: %d", videoThread.getLostFrames()), fontX, fontY - (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>
|
||||
*/
|
||||
public void pause(){
|
||||
if(videoThread != null)
|
||||
videoThread.pause();
|
||||
|
||||
states[currState.getValue()].pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Resumes the video streaming and the current state.</p>
|
||||
*/
|
||||
public void resume(){
|
||||
if(videoThread != null)
|
||||
videoThread.play();
|
||||
|
||||
states[currState.getValue()].resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clear graphic resources</p>
|
||||
*/
|
||||
public void dispose(){
|
||||
// Finish network threads.
|
||||
videoThread.finish();
|
||||
robotThread.finish();
|
||||
|
||||
// Dispose graphic objects.
|
||||
fadeTexture.dispose();
|
||||
batch.dispose();
|
||||
if(ProjectConstants.DEBUG){
|
||||
font.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();
|
||||
|
||||
ScenarioGlobals.dispose();
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; APPLICATION EVENTS LISTENER INTERFACE METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public synchronized void networkStreamConnected(String streamName){
|
||||
//if(streamName.equals(VideoStreamingThread.THREAD_NAME) || streamName.equals(RobotControlThread.THREAD_NAME))
|
||||
public synchronized void onNetworkStreamConnected(String streamName){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".networkStreamConnected() :: Stream " + streamName + " connected.");
|
||||
connections += 1;
|
||||
if(connections >= 2){
|
||||
|
||||
if(connections >= 3){
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast.");
|
||||
serviceDiscoveryThread.finish();
|
||||
mcastEnabler.disableMulticast();
|
||||
toaster.showShortToast("Client connected");
|
||||
if(actionResolver != null) actionResolver.disableMulticast();
|
||||
if(actionResolver != null) actionResolver.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>
|
||||
* @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(toaster != null){
|
||||
if(longToast) toaster.showLongToast(msg);
|
||||
else toaster.showShortToast(msg);
|
||||
if(actionResolver != null){
|
||||
if(longToast) actionResolver.showLongToast(msg);
|
||||
else actionResolver.showShortToast(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.interfaces;
|
||||
package ve.ucv.ciens.ccg.nxtar.components;
|
||||
|
||||
public interface CVProcessor {
|
||||
public class CVData{
|
||||
public byte[] outFrame;
|
||||
public int[] markerCodes;
|
||||
// TODO: Add marker location data.
|
||||
import com.artemis.Component;
|
||||
|
||||
public class CollisionDetectionComponent extends Component {
|
||||
public boolean colliding;
|
||||
|
||||
public CollisionDetectionComponent(){
|
||||
this.colliding = false;
|
||||
}
|
||||
|
||||
public CVData processFrame(byte[] frame, int w, int h);
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
129
src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java
Normal file
129
src/ve/ucv/ciens/ccg/nxtar/components/FadeEffectComponent.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
38
src/ve/ucv/ciens/ccg/nxtar/components/GeometryComponent.java
Normal file
38
src/ve/ucv/ciens/ccg/nxtar/components/GeometryComponent.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.Matrix3;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
public class GeometryComponent extends Component {
|
||||
public Vector3 position;
|
||||
public Matrix3 rotation;
|
||||
public Vector3 scaling;
|
||||
|
||||
public GeometryComponent(){
|
||||
this.position = new Vector3();
|
||||
this.rotation = new Matrix3();
|
||||
this.scaling = new Vector3(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public GeometryComponent(Vector3 position, Matrix3 rotation, Vector3 scaling){
|
||||
this.position = new Vector3(position);
|
||||
this.rotation = new Matrix3(rotation);
|
||||
this.scaling = new Vector3(scaling);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 MarkerCodeComponent extends Component {
|
||||
public int code;
|
||||
public boolean enabled;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Tag class.
|
||||
*/
|
||||
public abstract class PlayerComponentBase extends Component {
|
||||
public static final String PLAYER_GROUP = "PLAYER";
|
||||
|
||||
public boolean gameFinished;
|
||||
public boolean victory;
|
||||
|
||||
public PlayerComponentBase(){
|
||||
this.gameFinished = false;
|
||||
this.victory = false;
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
this.gameFinished = false;
|
||||
this.victory = false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
30
src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java
Normal file
30
src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.Shader;
|
||||
|
||||
public class ShaderComponent extends Component{
|
||||
public Shader shader;
|
||||
|
||||
public ShaderComponent(Shader shader) throws IllegalArgumentException{
|
||||
if(shader == null)
|
||||
throw new IllegalArgumentException("Shader is null.");
|
||||
|
||||
this.shader = shader;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
86
src/ve/ucv/ciens/ccg/nxtar/entities/EntityCreatorBase.java
Normal file
86
src/ve/ucv/ciens/ccg/nxtar/entities/EntityCreatorBase.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
/**
|
||||
* <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{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <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();
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.PerspectiveCamera;
|
||||
import com.badlogic.gdx.math.Matrix4;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
/**
|
||||
* <p>Extension of the standard LibGDX perspective camera that allows setting an
|
||||
* arbitrary projection matrix when updating.</p>
|
||||
*/
|
||||
public class CustomPerspectiveCamera extends PerspectiveCamera{
|
||||
private final Vector3 tmp = new Vector3();
|
||||
|
||||
public CustomPerspectiveCamera(float fieldOfView, float viewportWidth, float viewportHeight){
|
||||
super(fieldOfView, viewportWidth, 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);
|
||||
|
||||
if(updateFrustum){
|
||||
invProjectionView.set(combined).inv();
|
||||
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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
32
src/ve/ucv/ciens/ccg/nxtar/input/GamepadUserInput.java
Normal file
32
src/ve/ucv/ciens/ccg/nxtar/input/GamepadUserInput.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
32
src/ve/ucv/ciens/ccg/nxtar/input/KeyboardUserInput.java
Normal file
32
src/ve/ucv/ciens/ccg/nxtar/input/KeyboardUserInput.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
34
src/ve/ucv/ciens/ccg/nxtar/input/TouchUserInput.java
Normal file
34
src/ve/ucv/ciens/ccg/nxtar/input/TouchUserInput.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Miguel Angel Astor Romero
|
||||
* 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.
|
||||
@@ -13,8 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.interfaces;
|
||||
package ve.ucv.ciens.ccg.nxtar.input;
|
||||
|
||||
public interface NetworkConnectionListener {
|
||||
public void networkStreamConnected(String streamName);
|
||||
}
|
||||
/**
|
||||
* Tag class for different user interaction wrapper classes.
|
||||
*/
|
||||
public abstract class UserInput{ }
|
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.interfaces;
|
||||
|
||||
public interface Toaster {
|
||||
public interface ActionResolver{
|
||||
public void showShortToast(String msg);
|
||||
public void showLongToast(String msg);
|
||||
public void enableMulticast();
|
||||
public void disableMulticast();
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.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();
|
||||
}
|
86
src/ve/ucv/ciens/ccg/nxtar/interfaces/ImageProcessor.java
Normal file
86
src/ve/ucv/ciens/ccg/nxtar/interfaces/ImageProcessor.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.interfaces;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||
|
||||
import com.badlogic.gdx.math.Matrix3;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
public interface ImageProcessor{
|
||||
public class MarkerData{
|
||||
public byte[] outFrame;
|
||||
public int[] markerCodes;
|
||||
public Vector3[] translationVectors;
|
||||
public Matrix3[] rotationMatrices;
|
||||
}
|
||||
|
||||
public class CalibrationData{
|
||||
public byte[] outFrame;
|
||||
public float[] calibrationPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Finds up to {@link ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS} markers in the input
|
||||
* image and returns their codes and pose estimation in the CVMarkerData structure. The
|
||||
* markers are higlihted in the input image.</p>
|
||||
*
|
||||
* @param frame The JPEG encoded input image.
|
||||
* @return A data structure containing the processed output image, the
|
||||
* detected marker codes and their respective locations.
|
||||
*/
|
||||
public MarkerData findMarkersInFrame(byte[] frame);
|
||||
|
||||
/**
|
||||
* <p>Attempts to detect a checkerboard calibration pattern in the input image.
|
||||
* If the pattenr is found the method returns an image with the pattern
|
||||
* highlighted and the spatial location of the calibration points in the
|
||||
* output data structure.</p>
|
||||
*
|
||||
* @param frame The JPEG encoded input image.
|
||||
* @return A data structure containing the processed output image and the
|
||||
* location of the calibration points. If the pattern was not found, the returnd
|
||||
* calibration points array is null.
|
||||
*/
|
||||
public CalibrationData findCalibrationPattern(byte[] frame);
|
||||
|
||||
/**
|
||||
* <p>Obtains the intrinsic camera parameters necesary for calibration.</p>
|
||||
*/
|
||||
public void calibrateCamera(float[][] calibrationSamples, byte[] frame);
|
||||
|
||||
/**
|
||||
* <p>Removes camera lens distortion from the input image using the
|
||||
* camera parameters obtained by the calibrateCamera method.</p>
|
||||
*
|
||||
* @return A JPEG encoded image that is the input image after distortion correction. If the
|
||||
* camera has not been calibrated or OpenCV failed to load returns null.
|
||||
*/
|
||||
public byte[] undistortFrame(byte[] frame);
|
||||
|
||||
/**
|
||||
* <p>Indicates if OpenCV has been sucessfully initialized and used
|
||||
* to obtain the camera parameters for calibration.</p>
|
||||
*
|
||||
* @return True if and only if OpenCV initialized succesfully and calibrateCamera has been called previously.
|
||||
*/
|
||||
public boolean isCameraCalibrated();
|
||||
|
||||
public float getFocalPointX();
|
||||
public float getFocalPointY();
|
||||
public float getCameraCenterX();
|
||||
public float getCameraCenterY();
|
||||
}
|
@@ -24,7 +24,7 @@ import java.net.Socket;
|
||||
|
||||
import ve.ucv.ciens.ccg.networkdata.MotorEvent;
|
||||
import ve.ucv.ciens.ccg.networkdata.MotorEventACK;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.NetworkConnectionListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue;
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||
|
||||
@@ -34,8 +34,9 @@ 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 NetworkConnectionListener netListener;
|
||||
private ApplicationEventsListener netListener;
|
||||
private ServerSocket server;
|
||||
private Socket client;
|
||||
private MotorEventQueue queue;
|
||||
@@ -62,14 +63,22 @@ public class RobotControlThread extends Thread {
|
||||
}
|
||||
|
||||
private static class SingletonHolder{
|
||||
public static final RobotControlThread INSTANCE = new RobotControlThread();
|
||||
public static RobotControlThread INSTANCE;
|
||||
}
|
||||
|
||||
public static RobotControlThread getInstance(){
|
||||
if(refCount == 0)
|
||||
SingletonHolder.INSTANCE = new RobotControlThread();
|
||||
refCount++;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
public void addNetworkConnectionListener(NetworkConnectionListener listener){
|
||||
public static void freeInstance(){
|
||||
refCount--;
|
||||
if(refCount == 0) SingletonHolder.INSTANCE = null;
|
||||
}
|
||||
|
||||
public void addNetworkConnectionListener(ApplicationEventsListener listener){
|
||||
netListener = listener;
|
||||
}
|
||||
|
||||
@@ -87,6 +96,11 @@ 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
|
||||
@@ -97,7 +111,7 @@ public class RobotControlThread extends Thread {
|
||||
try{
|
||||
client = server.accept();
|
||||
client.setTcpNoDelay(true);
|
||||
if(netListener != null) netListener.networkStreamConnected(THREAD_NAME);
|
||||
if(netListener != null) netListener.onNetworkStreamConnected(THREAD_NAME);
|
||||
os = new ObjectOutputStream(client.getOutputStream());
|
||||
is = new ObjectInputStream(client.getInputStream());
|
||||
|
||||
@@ -168,7 +182,6 @@ public class RobotControlThread extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try{
|
||||
client.close();
|
||||
}catch(IOException io){
|
||||
|
@@ -15,22 +15,134 @@
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
|
||||
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;
|
||||
private Socket client;
|
||||
private Object pauseMonitor;
|
||||
private boolean paused;
|
||||
private boolean done;
|
||||
private InputStream reader;
|
||||
private Byte lightReading;
|
||||
|
||||
private SensorReportThread(){
|
||||
paused = false;
|
||||
done = false;
|
||||
netListener = null;
|
||||
pauseMonitor = null;
|
||||
client = null;
|
||||
lightReading = -1;
|
||||
|
||||
try{
|
||||
server = new ServerSocket(ProjectConstants.SENSOR_REPORT_PORT);
|
||||
}catch(IOException io){
|
||||
Gdx.app.error(TAG, CLASS_NAME + ".RobotControlThread() :: Error creating server: " + io.getMessage(), io);
|
||||
server = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SingletonHolder{
|
||||
public final static SensorReportThread INSTANCE = new SensorReportThread();
|
||||
public static SensorReportThread INSTANCE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void pauseThread(){
|
||||
synchronized(pauseMonitor){
|
||||
paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void resumeThread(){
|
||||
synchronized(pauseMonitor){
|
||||
paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
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(){
|
||||
byte data;
|
||||
|
||||
synchronized(lightReading){
|
||||
data = lightReading.byteValue();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
byte[] reading = new byte[1];
|
||||
|
||||
try{
|
||||
client = server.accept();
|
||||
client.setTcpNoDelay(true);
|
||||
if(netListener != null) netListener.onNetworkStreamConnected(THREAD_NAME);
|
||||
reader = client.getInputStream();
|
||||
|
||||
}catch(IOException io){
|
||||
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error accepting client: " + io.getMessage(), io);
|
||||
return;
|
||||
}
|
||||
|
||||
while(!paused){
|
||||
if(done) break;
|
||||
|
||||
try{
|
||||
reader.read(reading);
|
||||
}catch(IOException io){
|
||||
Gdx.app.error(TAG, CLASS_NAME + ".run() :: IOException during sensor read: " + io.getMessage(), io);
|
||||
break;
|
||||
}
|
||||
|
||||
synchronized (lightReading) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -38,35 +38,28 @@ import com.badlogic.gdx.Gdx;
|
||||
* @author miky
|
||||
*/
|
||||
public class ServiceDiscoveryThread extends Thread {
|
||||
/**
|
||||
* The name used to identify this thread.
|
||||
*/
|
||||
public static final String THREAD_NAME = "ServiceDiscoveryThread";
|
||||
/**
|
||||
* Tag used for logging.
|
||||
*/
|
||||
public static final String THREAD_NAME = "ServiceDiscoveryThread";
|
||||
private static final String TAG = "NXTAR_CORE_UDPTHREAD";
|
||||
/**
|
||||
* Class name used for logging.
|
||||
*/
|
||||
private static final String CLASS_NAME = ServiceDiscoveryThread.class.getSimpleName();
|
||||
/**
|
||||
* Maximum number of transmission attempts before ending the thread abruptly.
|
||||
*/
|
||||
private static final int MAX_RETRIES = 5;
|
||||
private static final int MAX_RETRIES = 5;
|
||||
|
||||
private static int refCount = 0;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -101,7 +94,7 @@ public class ServiceDiscoveryThread extends Thread {
|
||||
* Singleton holder for this class.
|
||||
*/
|
||||
private static class SingletonHolder{
|
||||
public static final ServiceDiscoveryThread INSTANCE = new ServiceDiscoveryThread();
|
||||
public static ServiceDiscoveryThread INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +103,17 @@ 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.
|
||||
*
|
||||
@@ -138,6 +139,7 @@ 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;
|
||||
}
|
||||
|
@@ -20,10 +20,9 @@ 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.NetworkConnectionListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
|
||||
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||
|
||||
@@ -33,15 +32,15 @@ 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 NetworkConnectionListener netListener;
|
||||
private ApplicationEventsListener netListener;
|
||||
private DatagramSocket socket;
|
||||
private boolean protocolStarted;
|
||||
private boolean done;
|
||||
private boolean pause;
|
||||
private boolean coreNotified;
|
||||
private Object protocolPauseMonitor;
|
||||
private Socket client;
|
||||
private VideoFrameMonitor frameMonitor;
|
||||
private long then;
|
||||
private long now;
|
||||
@@ -72,14 +71,22 @@ public class VideoStreamingThread extends Thread{
|
||||
}
|
||||
|
||||
private static class SingletonHolder{
|
||||
public static final VideoStreamingThread INSTANCE = new VideoStreamingThread();
|
||||
public static VideoStreamingThread INSTANCE;
|
||||
}
|
||||
|
||||
public static VideoStreamingThread getInstance(){
|
||||
if(refCount == 0)
|
||||
SingletonHolder.INSTANCE = new VideoStreamingThread();
|
||||
refCount++;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
public void addNetworkConnectionListener(NetworkConnectionListener listener){
|
||||
public static void freeInstance(){
|
||||
refCount--;
|
||||
if(refCount == 0) SingletonHolder.INSTANCE = null;
|
||||
}
|
||||
|
||||
public void addNetworkConnectionListener(ApplicationEventsListener listener){
|
||||
netListener = listener;
|
||||
}
|
||||
|
||||
@@ -138,9 +145,10 @@ public class VideoStreamingThread extends Thread{
|
||||
VideoFrameDataMessage dataMessage;
|
||||
Object tmpMessage;
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message size from socket.");
|
||||
//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());
|
||||
@@ -148,11 +156,11 @@ public class VideoStreamingThread extends Thread{
|
||||
return;
|
||||
}
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Creating buffers.");
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Creating buffers.");
|
||||
intSize = byteArray2Int(size);
|
||||
data = new byte[intSize];
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message from socket.");
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message from socket.");
|
||||
try{
|
||||
packet = new DatagramPacket(data, data.length);
|
||||
socket.receive(packet);
|
||||
@@ -164,17 +172,16 @@ public class VideoStreamingThread extends Thread{
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Saving message in monitor.");
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Saving message in monitor.");
|
||||
try{
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
tmpMessage = ois.readObject();
|
||||
|
||||
if(tmpMessage instanceof VideoFrameDataMessage){
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received a data message.");
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received a data message.");
|
||||
dataMessage = (VideoFrameDataMessage) tmpMessage;
|
||||
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received frame dimensions are: " +
|
||||
Integer.toString(dataMessage.imageWidth) + "x" + Integer.toString(dataMessage.imageHeight));
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received frame dimensions are: " + Integer.toString(dataMessage.imageWidth) + "x" + Integer.toString(dataMessage.imageHeight));
|
||||
frameMonitor.setFrameDimensions(dataMessage.imageWidth, dataMessage.imageHeight);
|
||||
frameMonitor.setNewFrame(dataMessage.data);
|
||||
|
||||
@@ -201,7 +208,7 @@ public class VideoStreamingThread extends Thread{
|
||||
public int getFps(){
|
||||
return fps;
|
||||
}
|
||||
|
||||
|
||||
public int getLostFrames(){
|
||||
return lostFrames;
|
||||
}
|
||||
@@ -218,10 +225,10 @@ public class VideoStreamingThread extends Thread{
|
||||
try{ pauseMonitor.wait(); }catch(InterruptedException ie){ }
|
||||
}
|
||||
}
|
||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Receiving.");
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Receiving.");
|
||||
if(netListener != null && !coreNotified && frameMonitor.getCurrentFrame() != null){
|
||||
coreNotified = true;
|
||||
netListener.networkStreamConnected(THREAD_NAME);
|
||||
netListener.onNetworkStreamConnected(THREAD_NAME);
|
||||
}
|
||||
receiveUdp();
|
||||
frames++;
|
||||
@@ -237,12 +244,6 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -251,7 +252,7 @@ public class VideoStreamingThread extends Thread{
|
||||
pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void play(){
|
||||
synchronized (pauseMonitor){
|
||||
pause = false;
|
||||
|
@@ -61,14 +61,11 @@ 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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +73,6 @@ public class VideoFrameMonitor{
|
||||
byte[] frame;
|
||||
|
||||
synchronized(frameMonitor){
|
||||
//Gdx.app.debug(TAG, CLASS_NAME + ".getCurrentFrame() :: Fetching frameB.");
|
||||
frame = frameB;
|
||||
}
|
||||
return frame;
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/HintsOverlayBase.java
Normal file
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/HintsOverlayBase.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Miguel Angel Astor Romero
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.scenarios;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
/**
|
||||
* <p>Base class for hint screens.</p>
|
||||
*/
|
||||
public abstract class HintsOverlayBase implements Disposable{
|
||||
/**
|
||||
* <p>Renders the overlay.</p>
|
||||
*
|
||||
* @param batch The {@link SpriteBatch} to use for rendering.
|
||||
*/
|
||||
public abstract void render(SpriteBatch batch);
|
||||
}
|
249
src/ve/ucv/ciens/ccg/nxtar/scenarios/ScenarioGlobals.java
Normal file
249
src/ve/ucv/ciens/ccg/nxtar/scenarios/ScenarioGlobals.java
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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.ObjectRenderingSystem;
|
||||
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 ObjectRenderingSystem(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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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(){}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Miguel Angel Astor Romero
|
||||
* 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.
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.interfaces;
|
||||
package ve.ucv.ciens.ccg.nxtar.scenarios;
|
||||
|
||||
public interface MulticastEnabler {
|
||||
public void enableMulticast();
|
||||
public void disableMulticast();
|
||||
}
|
||||
public abstract class SummaryBase{
|
||||
public abstract void reset();
|
||||
}
|
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/SummaryOverlayBase.java
Normal file
31
src/ve/ucv/ciens/ccg/nxtar/scenarios/SummaryOverlayBase.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Miguel Angel Astor Romero
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.scenarios;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
/**
|
||||
* <p>Base class for 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);
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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 GOAL_FLOOR_MIN_LUMINANCE = 75;
|
||||
private static final int MARKER_NEARBY_FLOOR_MIN_LUMINANCE = 45;
|
||||
|
||||
private enum action_state_t{
|
||||
START, WALK_FORWARD, DETECT_MARKER, FINISHING, END;
|
||||
}
|
||||
|
||||
public class BombGameAutomaticActionSummary extends SummaryBase{
|
||||
private int numCombinationBombs;
|
||||
private int numInclinationBombs;
|
||||
private int numWireBombs;
|
||||
|
||||
public BombGameAutomaticActionSummary(){
|
||||
reset();
|
||||
}
|
||||
|
||||
public int getNumCombinationBombs() {
|
||||
return numCombinationBombs;
|
||||
}
|
||||
|
||||
public int getNumInclinationBombs() {
|
||||
return numInclinationBombs;
|
||||
}
|
||||
|
||||
public int getNumWireBombs() {
|
||||
return numWireBombs;
|
||||
}
|
||||
|
||||
public void addCombinationBomb(){
|
||||
numCombinationBombs++;
|
||||
}
|
||||
|
||||
public void addInclinationBomb(){
|
||||
numInclinationBombs++;
|
||||
}
|
||||
|
||||
public void addWireBomb(){
|
||||
numWireBombs++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.numCombinationBombs = 0;
|
||||
this.numInclinationBombs = 0;
|
||||
this.numWireBombs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private automatic_action_t nextAction;
|
||||
private action_state_t state;
|
||||
private List<Integer> detectedMarkers;
|
||||
private float then;
|
||||
private float now;
|
||||
private GroupManager manager;
|
||||
private BombGameAutomaticActionSummary summary;
|
||||
|
||||
public BombGameAutomaticActionPerformer(){
|
||||
nextAction = automatic_action_t.NO_ACTION;
|
||||
state = action_state_t.START;
|
||||
detectedMarkers = new LinkedList<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 markerDetected = 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.");
|
||||
summary.reset();
|
||||
nextAction = automatic_action_t.ROTATE_90;
|
||||
state = action_state_t.WALK_FORWARD;
|
||||
finish = false;
|
||||
break;
|
||||
|
||||
case WALK_FORWARD:
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is WALK_FORWARD.");
|
||||
if(lightSensorReading >= GOAL_FLOOR_MIN_LUMINANCE){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Found goal.");
|
||||
nextAction = automatic_action_t.STOP;
|
||||
state = action_state_t.FINISHING;
|
||||
}else{
|
||||
if(lightSensorReading >= MARKER_NEARBY_FLOOR_MIN_LUMINANCE && lightSensorReading < GOAL_FLOOR_MIN_LUMINANCE){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): There is a marker nearby.");
|
||||
nextAction = automatic_action_t.STOP;
|
||||
state = action_state_t.DETECT_MARKER;
|
||||
then = Gdx.graphics.getDeltaTime();
|
||||
}else{
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Walking.");
|
||||
nextAction = automatic_action_t.GO_FORWARD;
|
||||
}
|
||||
}
|
||||
finish = false;
|
||||
break;
|
||||
|
||||
case DETECT_MARKER:
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is DETECT_MARKER.");
|
||||
for(int i = 0; !markerDetected && i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){
|
||||
// Check if this marker has not been detected already.
|
||||
for(Integer code : detectedMarkers){
|
||||
if(markers.markerCodes[i] == code){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Marker already detected.");
|
||||
markerDetected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the marker has not been detected before then examine it.
|
||||
if(!markerDetected){
|
||||
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(!markerDetected && detectedCode != -1)
|
||||
detectedMarkers.add(detectedCode);
|
||||
|
||||
if(lightSensorReading < MARKER_NEARBY_FLOOR_MIN_LUMINANCE){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Switching to WALK_FORWARD.");
|
||||
state = action_state_t.WALK_FORWARD;
|
||||
nextAction = automatic_action_t.STOP;
|
||||
then = 0.0f;
|
||||
now = 0.0f;
|
||||
}else{
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): Clearing MARKER_NEARBY_FLOOR.");
|
||||
now += Gdx.graphics.getDeltaTime();
|
||||
deltaT = now - then;
|
||||
if(deltaT >= 2.0f){
|
||||
nextAction = automatic_action_t.GO_FORWARD;
|
||||
then = Gdx.graphics.getDeltaTime();
|
||||
now = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
finish = false;
|
||||
|
||||
break;
|
||||
|
||||
case FINISHING:
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".performAutomaticAction(): State is FINISHING.");
|
||||
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.");
|
||||
nextAction = automatic_action_t.NO_ACTION;
|
||||
state = action_state_t.START;
|
||||
finish = true;
|
||||
now = 0.0f;
|
||||
then = 0.0f;
|
||||
detectedMarkers.clear();
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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.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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Miguel Angel Astor Romero
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
699
src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java
Normal file
699
src/ve/ucv/ciens/ccg/nxtar/states/AutomaticActionState.java
Normal file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Miguel Angel Astor Romero
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.states;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
|
||||
import ve.ucv.ciens.ccg.nxtar.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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,88 +1,165 @@
|
||||
/*
|
||||
* 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.InputProcessor;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.controllers.Controller;
|
||||
import com.badlogic.gdx.controllers.ControllerListener;
|
||||
import com.badlogic.gdx.controllers.PovDirection;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
public abstract class BaseState implements Screen, ControllerListener, InputProcessor {
|
||||
protected NxtARCore core;
|
||||
protected boolean stateActive;
|
||||
|
||||
/* STATE METHODS */
|
||||
public abstract void onStateSet();
|
||||
public abstract void onStateUnset();
|
||||
|
||||
/* SCREEN METHODS*/
|
||||
@Override
|
||||
public abstract void render(float delta);
|
||||
@Override
|
||||
public abstract void resize(int width, int height);
|
||||
@Override
|
||||
public abstract void show();
|
||||
@Override
|
||||
public abstract void hide();
|
||||
@Override
|
||||
public abstract void pause();
|
||||
@Override
|
||||
public abstract void resume();
|
||||
@Override
|
||||
public abstract void dispose();
|
||||
|
||||
/* INPUT PROCESSOR METHODS. */
|
||||
@Override
|
||||
public abstract boolean keyDown(int keycode);
|
||||
@Override
|
||||
public abstract boolean keyUp(int keycode);
|
||||
@Override
|
||||
public abstract boolean keyTyped(char character);
|
||||
@Override
|
||||
public abstract boolean touchDown(int screenX, int screenY, int pointer, int button);
|
||||
@Override
|
||||
public abstract boolean touchUp(int screenX, int screenY, int pointer, int button);
|
||||
@Override
|
||||
public abstract boolean touchDragged(int screenX, int screenY, int pointer);
|
||||
@Override
|
||||
public abstract boolean mouseMoved(int screenX, int screenY);
|
||||
@Override
|
||||
public abstract boolean scrolled(int amount);
|
||||
|
||||
/* CONTROLLER LISTENER METHODS. */
|
||||
@Override
|
||||
public abstract void connected(Controller controller);
|
||||
@Override
|
||||
public abstract void disconnected(Controller controller);
|
||||
@Override
|
||||
public abstract boolean buttonDown(Controller controller, int buttonCode);
|
||||
@Override
|
||||
public abstract boolean buttonUp(Controller controller, int buttonCode);
|
||||
@Override
|
||||
public abstract boolean axisMoved(Controller controller, int axisCode, float value);
|
||||
@Override
|
||||
public abstract boolean povMoved(Controller controller, int povCode, PovDirection value);
|
||||
@Override
|
||||
public abstract boolean xSliderMoved(Controller controller, int sliderCode, boolean value);
|
||||
@Override
|
||||
public abstract boolean ySliderMoved(Controller controller, int sliderCode, boolean value);
|
||||
@Override
|
||||
public abstract boolean accelerometerMoved(Controller controller, int accelerometerCode, Vector3 value);
|
||||
}
|
||||
/*
|
||||
* 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.InputProcessor;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.controllers.Controller;
|
||||
import com.badlogic.gdx.controllers.ControllerListener;
|
||||
import com.badlogic.gdx.controllers.PovDirection;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
public abstract class BaseState implements Screen, ControllerListener, InputProcessor{
|
||||
protected NxtARCore core;
|
||||
protected boolean stateActive;
|
||||
protected OrthographicCamera pixelPerfectCamera;
|
||||
protected Vector3 win2world;
|
||||
protected Vector2 touchPointWorldCoords;
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;
|
||||
; STATE METHODS ;
|
||||
;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
public abstract void onStateSet();
|
||||
public abstract void onStateUnset();
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;
|
||||
; SCREEN METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public abstract void render(float delta);
|
||||
|
||||
@Override
|
||||
public abstract void dispose();
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height){ }
|
||||
|
||||
@Override
|
||||
public void show(){ }
|
||||
|
||||
@Override
|
||||
public void hide(){ }
|
||||
|
||||
@Override
|
||||
public void pause(){ }
|
||||
|
||||
@Override
|
||||
public void resume(){ }
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;
|
||||
; HELPER METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
protected final void unprojectTouch(int screenX, int screenY){
|
||||
win2world.set(screenX, screenY, 0.0f);
|
||||
pixelPerfectCamera.unproject(win2world);
|
||||
touchPointWorldCoords.set(win2world.x, win2world.y);
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; INPUT PROCESSOR METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keycode){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(char character){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int screenX, int screenY, int pointer, int button){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean touchUp(int screenX, int screenY, int pointer, int button){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean touchDragged(int screenX, int screenY, int pointer){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(int screenX, int screenY){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean scrolled(int amount){
|
||||
return false;
|
||||
};
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; CONTROLLER LISTENER METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public void connected(Controller controller){ };
|
||||
|
||||
@Override
|
||||
public void disconnected(Controller controller){ };
|
||||
|
||||
@Override
|
||||
public boolean buttonDown(Controller controller, int buttonCode){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean buttonUp(Controller controller, int buttonCode){
|
||||
return false;
|
||||
};
|
||||
@Override
|
||||
public boolean axisMoved(Controller controller, int axisCode, float value){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean povMoved(Controller controller, int povCode, PovDirection value){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean xSliderMoved(Controller controller, int sliderCode, boolean value){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean ySliderMoved(Controller controller, int sliderCode, boolean value){
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean accelerometerMoved(Controller controller, int accelerometerCode, Vector3 value){
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
234
src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java
Normal file
234
src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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 java.util.Arrays;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
|
||||
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.CalibrationData;
|
||||
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||
import ve.ucv.ciens.ccg.nxtar.utils.Size;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.Texture.TextureFilter;
|
||||
import com.badlogic.gdx.graphics.Texture.TextureWrap;
|
||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
|
||||
|
||||
public class CameraCalibrationState extends BaseState{
|
||||
private static final String TAG = "CAMERA_CALIBRATION_STATE";
|
||||
private static final String CLASS_NAME = CameraCalibrationState.class.getSimpleName();
|
||||
private static final String SHADER_PATH = "shaders/bckg/bckg";
|
||||
|
||||
private NxtARCore core;
|
||||
private boolean cameraCalibrated;
|
||||
|
||||
private float u_scaling[];
|
||||
protected Sprite background;
|
||||
private Texture backgroundTexture;
|
||||
private ShaderProgram backgroundShader;
|
||||
|
||||
// Cameras.
|
||||
private OrthographicCamera camera;
|
||||
|
||||
// Video stream graphics.
|
||||
private Texture videoFrameTexture;
|
||||
private Sprite renderableVideoFrame;
|
||||
private Pixmap videoFrame;
|
||||
|
||||
// Monitors.
|
||||
private VideoFrameMonitor frameMonitor;
|
||||
|
||||
private float[][] calibrationSamples;
|
||||
private int lastSampleTaken;
|
||||
|
||||
public CameraCalibrationState(final NxtARCore core){
|
||||
this.core = core;
|
||||
frameMonitor = VideoFrameMonitor.getInstance();
|
||||
cameraCalibrated = false;
|
||||
|
||||
// Set up the cameras.
|
||||
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
camera = new OrthographicCamera(1.0f, Gdx.graphics.getHeight() / Gdx.graphics.getWidth());
|
||||
|
||||
// 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));
|
||||
|
||||
// Load the background shader.
|
||||
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 + ".CameraCalibrationState() :: Failed to compile the background shader.");
|
||||
Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog());
|
||||
backgroundShader = null;
|
||||
}
|
||||
|
||||
// Set up the background scaling.
|
||||
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;
|
||||
|
||||
// Initialize the calibration samples vector.
|
||||
calibrationSamples = new float[ProjectConstants.CALIBRATION_SAMPLES][];
|
||||
for(int i = 0; i < calibrationSamples.length; i++){
|
||||
calibrationSamples[i] = new float[ProjectConstants.CALIBRATION_PATTERN_POINTS * 2];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateSet(){
|
||||
Gdx.input.setInputProcessor(this);
|
||||
Gdx.input.setCatchBackKey(true);
|
||||
Gdx.input.setCatchMenuKey(true);
|
||||
|
||||
lastSampleTaken = 0;
|
||||
cameraCalibrated = false;
|
||||
|
||||
for(int i = 0; i < calibrationSamples.length; i++){
|
||||
for(int j = 0; j < calibrationSamples[i].length; j++){
|
||||
calibrationSamples[i][j] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUnset(){ }
|
||||
|
||||
@Override
|
||||
public void render(float delta){
|
||||
byte[] frame;
|
||||
byte[] prevFrame = null;
|
||||
Size dimensions = null;
|
||||
|
||||
// Clear the screen.
|
||||
Gdx.gl.glClearColor(1, 1, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Render the background.
|
||||
core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||
core.batch.begin();{
|
||||
if(backgroundShader != null){
|
||||
core.batch.setShader(backgroundShader);
|
||||
backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2);
|
||||
}
|
||||
background.draw(core.batch);
|
||||
if(backgroundShader != null) core.batch.setShader(null);
|
||||
}core.batch.end();
|
||||
|
||||
// Fetch the current video frame.
|
||||
frame = frameMonitor.getCurrentFrame();
|
||||
|
||||
// Find the calibration points in the video frame.
|
||||
CalibrationData data = core.cvProc.findCalibrationPattern(frame);
|
||||
|
||||
// If the user requested a sample be taken.
|
||||
if(!cameraCalibrated && data.calibrationPoints != null){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".render(): Sample taken.");
|
||||
|
||||
// Save the calibration points to the samples array.
|
||||
for(int i = 0; i < data.calibrationPoints.length; i += 2){
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".render(): Value " + Integer.toString(i) + " = (" + Float.toString(data.calibrationPoints[i]) + ", " + Float.toString(data.calibrationPoints[i + 1]) + ")");
|
||||
calibrationSamples[lastSampleTaken][i] = data.calibrationPoints[i];
|
||||
calibrationSamples[lastSampleTaken][i + 1] = data.calibrationPoints[i + 1];
|
||||
}
|
||||
|
||||
// Move to the next sample.
|
||||
lastSampleTaken++;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame != null && data != null && data.outFrame != null && !Arrays.equals(frame, prevFrame)){
|
||||
// If the received frame is valid and is different from the previous frame.
|
||||
// Make a texture from the frame.
|
||||
dimensions = frameMonitor.getFrameDimensions();
|
||||
videoFrame = new Pixmap(data.outFrame, 0, dimensions.getWidth() * dimensions.getHeight());
|
||||
videoFrameTexture = new Texture(videoFrame);
|
||||
videoFrameTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||
videoFrame.dispose();
|
||||
|
||||
// Set up the frame texture as a rendereable sprite.
|
||||
TextureRegion region = new TextureRegion(videoFrameTexture, 0, 0, dimensions.getWidth(), dimensions.getHeight());
|
||||
renderableVideoFrame = new Sprite(region);
|
||||
renderableVideoFrame.setOrigin(renderableVideoFrame.getWidth() / 2, renderableVideoFrame.getHeight() / 2);
|
||||
if(!Ouya.runningOnOuya){
|
||||
renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() );
|
||||
renderableVideoFrame.rotate90(true);
|
||||
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, 0.5f - renderableVideoFrame.getHeight());
|
||||
}else{
|
||||
float xSize = Gdx.graphics.getHeight() * (dimensions.getWidth() / dimensions.getHeight());
|
||||
renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
|
||||
renderableVideoFrame.rotate90(true);
|
||||
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2);
|
||||
}
|
||||
|
||||
// Render the frame.
|
||||
if(!Ouya.runningOnOuya) core.batch.setProjectionMatrix(camera.combined);
|
||||
else core.batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||
core.batch.begin();{
|
||||
renderableVideoFrame.draw(core.batch);
|
||||
}core.batch.end();
|
||||
|
||||
// Clear texture memory.
|
||||
videoFrameTexture.dispose();
|
||||
}
|
||||
|
||||
// Save this frame as previous to avoid processing the same frame twice when network latency is high.
|
||||
prevFrame = frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(){
|
||||
if(videoFrameTexture != null)
|
||||
videoFrameTexture.dispose();
|
||||
backgroundTexture.dispose();
|
||||
if(backgroundShader != null) backgroundShader.dispose();
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; INPUT LISTENER METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode){
|
||||
if(keycode == Input.Keys.BACK){
|
||||
core.nextState = game_states_t.MAIN_MENU;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
327
src/ve/ucv/ciens/ccg/nxtar/states/InstructionsState.java
Normal file
327
src/ve/ucv/ciens/ccg/nxtar/states/InstructionsState.java
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,351 +1,348 @@
|
||||
/*
|
||||
* 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.controllers.Controller;
|
||||
import com.badlogic.gdx.controllers.PovDirection;
|
||||
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||
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";
|
||||
|
||||
// Helper fields.
|
||||
protected boolean clientConnected;
|
||||
private float u_scaling[];
|
||||
protected OrthographicCamera pixelPerfectCamera;
|
||||
|
||||
// Buttons and other gui components.
|
||||
protected TextButton startButton;
|
||||
protected Rectangle startButtonBBox;
|
||||
protected Sprite clientConnectedLedOn;
|
||||
protected Sprite clientConnectedLedOff;
|
||||
protected Sprite background;
|
||||
|
||||
// Graphic data for the start button.
|
||||
private Texture startButtonEnabledTexture;
|
||||
private Texture startButtonDisabledTexture;
|
||||
private Texture startButtonPressedTexture;
|
||||
private NinePatch startButtonEnabled9p;
|
||||
private NinePatch startButtonDisabled9p;
|
||||
private NinePatch startButtonPressed9p;
|
||||
private BitmapFont font;
|
||||
|
||||
// Other graphics.
|
||||
private Texture clientConnectedLedOffTexture;
|
||||
private Texture clientConnectedLedOnTexture;
|
||||
private Texture backgroundTexture;
|
||||
private ShaderProgram backgroundShader;
|
||||
|
||||
// Button touch helper fields.
|
||||
private Vector3 win2world;
|
||||
protected Vector2 touchPointWorldCoords;
|
||||
protected boolean startButtonTouched;
|
||||
protected int startButtonTouchPointer;
|
||||
|
||||
public MainMenuStateBase(){
|
||||
TextureRegion region;
|
||||
|
||||
this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
|
||||
// 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.
|
||||
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf"));
|
||||
font = generator.generateFont(Ouya.runningOnOuya ? 60 : 40, ProjectConstants.FONT_CHARS, false);
|
||||
generator.dispose();
|
||||
|
||||
// Create the start button itself.
|
||||
TextButtonStyle tbs = new TextButtonStyle();
|
||||
tbs.font = font;
|
||||
tbs.up = new NinePatchDrawable(startButtonEnabled9p);
|
||||
tbs.checked = new NinePatchDrawable(startButtonPressed9p);
|
||||
tbs.disabled = new NinePatchDrawable(startButtonDisabled9p);
|
||||
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 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);
|
||||
|
||||
// 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"), Gdx.files.internal(SHADER_PATH + ".frag"));
|
||||
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;
|
||||
|
||||
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(){
|
||||
startButtonEnabledTexture.dispose();
|
||||
startButtonDisabledTexture.dispose();
|
||||
startButtonPressedTexture.dispose();
|
||||
clientConnectedLedOnTexture.dispose();
|
||||
clientConnectedLedOffTexture.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);
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;
|
||||
; HELPER METHODS ;
|
||||
;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
protected void unprojectTouch(int screenX, int screenY){
|
||||
win2world.set(screenX, screenY, 0.0f);
|
||||
pixelPerfectCamera.unproject(win2world);
|
||||
touchPointWorldCoords.set(win2world.x, win2world.y);
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; 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)){
|
||||
startButton.setChecked(true);
|
||||
startButtonTouched = true;
|
||||
startButtonTouchPointer = 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(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords)){
|
||||
startButton.setChecked(false);
|
||||
startButtonTouched = false;
|
||||
startButtonTouchPointer = -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(!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.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode){
|
||||
if(keycode == Input.Keys.BACK){
|
||||
// Ignore.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; INPUT LISTENER METHOD STUBS ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keycode){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(char character){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(int screenX, int screenY){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrolled(int amount){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(Controller controller){ }
|
||||
|
||||
@Override
|
||||
public void disconnected(Controller controller){ }
|
||||
|
||||
@Override
|
||||
public boolean buttonDown(Controller controller, int buttonCode){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonUp(Controller controller, int buttonCode){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean axisMoved(Controller controller, int axisCode, float value){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean povMoved(Controller controller, int povCode, PovDirection value){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean xSliderMoved(Controller controller, int sliderCode, boolean value){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ySliderMoved(Controller controller, int sliderCode, boolean value){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accelerometerMoved(Controller controller, int accelerometerCode, Vector3 value){
|
||||
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.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;
|
||||
}
|
||||
}
|
||||
|
@@ -1,125 +1,209 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public OuyaMainMenuState(final NxtARCore core){
|
||||
this.core = core;
|
||||
|
||||
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
|
||||
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
|
||||
|
||||
float ledYPos = (-(Gdx.graphics.getHeight() / 2) * 0.5f) + (startButton.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);
|
||||
|
||||
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);
|
||||
ouyaOButton.setPosition(startButton.getX() - ouyaOButton.getWidth() - 20, startButton.getY() + (ouyaOButton.getHeight() / 2));
|
||||
|
||||
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);
|
||||
}
|
||||
startButton.draw(core.batch, 1.0f);
|
||||
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) {
|
||||
if(stateActive){
|
||||
if(buttonCode == Ouya.BUTTON_O){
|
||||
if(!clientConnected){
|
||||
core.toast("Can't start the game. No client is connected.", true);
|
||||
}else{
|
||||
oButtonPressed = true;
|
||||
startButton.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonUp(Controller controller, int buttonCode) {
|
||||
if(stateActive){
|
||||
if(buttonCode == Ouya.BUTTON_O){
|
||||
if(oButtonPressed){
|
||||
oButtonPressed = false;
|
||||
startButton.setChecked(false);
|
||||
core.nextState = game_states_t.IN_GAME;
|
||||
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
@@ -1,202 +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 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 ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
|
||||
}
|
330
src/ve/ucv/ciens/ccg/nxtar/states/ScenarioEndSummaryState.java
Normal file
330
src/ve/ucv/ciens/ccg/nxtar/states/ScenarioEndSummaryState.java
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Miguel Angel Astor Romero
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ve.ucv.ciens.ccg.nxtar.states;
|
||||
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
|
||||
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
|
||||
import ve.ucv.ciens.ccg.nxtar.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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,56 +1,83 @@
|
||||
/*
|
||||
* 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){
|
||||
this.core = core;
|
||||
startButton.setPosition(-(startButton.getWidth() / 2), -(startButton.getHeight() / 2));
|
||||
startButtonBBox.setPosition(startButton.getX(), startButton.getY());
|
||||
|
||||
float ledYPos = (-(Gdx.graphics.getHeight() / 2) * 0.5f) + (startButton.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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
startButton.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 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();
|
||||
}
|
||||
}
|
||||
|
69
src/ve/ucv/ciens/ccg/nxtar/systems/AnimationSystem.java
Normal file
69
src/ve/ucv/ciens/ccg/nxtar/systems/AnimationSystem.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
121
src/ve/ucv/ciens/ccg/nxtar/systems/CollisionDetectionSystem.java
Normal file
121
src/ve/ucv/ciens/ccg/nxtar/systems/CollisionDetectionSystem.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
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();
|
||||
}
|
||||
}
|
30
src/ve/ucv/ciens/ccg/nxtar/systems/GameLogicSystemBase.java
Normal file
30
src/ve/ucv/ciens/ccg/nxtar/systems/GameLogicSystemBase.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 com.artemis.Aspect;
|
||||
import com.artemis.Entity;
|
||||
import com.artemis.systems.EntityProcessingSystem;
|
||||
|
||||
public abstract class GameLogicSystemBase extends EntityProcessingSystem {
|
||||
|
||||
public GameLogicSystemBase(Aspect aspect){
|
||||
super(aspect);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract void process(Entity e);
|
||||
}
|
103
src/ve/ucv/ciens/ccg/nxtar/systems/GeometrySystem.java
Normal file
103
src/ve/ucv/ciens/ccg/nxtar/systems/GeometrySystem.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.VisibilityComponent;
|
||||
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;
|
||||
|
||||
public class MarkerPositioningSystem extends EntityProcessingSystem {
|
||||
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
|
||||
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
|
||||
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
|
||||
|
||||
private MarkerData markers;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MarkerPositioningSystem(){
|
||||
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, VisibilityComponent.class));
|
||||
|
||||
markers = null;
|
||||
}
|
||||
|
||||
public void setMarkerData(MarkerData markers){
|
||||
this.markers = markers;
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
|
||||
for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){
|
||||
if(markers.markerCodes[i] != 1){
|
||||
if(markers.markerCodes[i] == marker.code){
|
||||
geometry.position.set(markers.translationVectors[i]);
|
||||
geometry.rotation.set(markers.rotationMatrices[i]);
|
||||
visibility.visible = true;
|
||||
break;
|
||||
}else{
|
||||
visibility.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.ShaderComponent;
|
||||
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.graphics.PerspectiveCamera;
|
||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
||||
|
||||
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;
|
||||
|
||||
private PerspectiveCamera camera;
|
||||
private ModelBatch batch;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MarkerRenderingSystem(ModelBatch batch){
|
||||
super(Aspect.getAspectForAll(ShaderComponent.class, EnvironmentComponent.class, RenderModelComponent.class, VisibilityComponent.class));
|
||||
|
||||
camera = null;
|
||||
this.batch = batch;
|
||||
}
|
||||
|
||||
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;
|
||||
RenderModelComponent model;
|
||||
ShaderComponent shader;
|
||||
VisibilityComponent visibility;
|
||||
|
||||
if(camera == null)
|
||||
return;
|
||||
|
||||
model = modelMapper.get(e);
|
||||
environment = environmentMapper.get(e);
|
||||
shader = shaderMapper.get(e);
|
||||
visibility = visibiltyMapper.get(e);
|
||||
|
||||
if(visibility.visible){
|
||||
// Render the marker;
|
||||
batch.render(model.instance, environment.environment, shader.shader);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.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.PerspectiveCamera;
|
||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
||||
|
||||
/**
|
||||
* <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<ShaderComponent> shaderMapper;
|
||||
@Mapper ComponentMapper<RenderModelComponent> modelMapper;
|
||||
@Mapper ComponentMapper<EnvironmentComponent> environmentMapper;
|
||||
|
||||
private PerspectiveCamera camera;
|
||||
private ModelBatch batch;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ObjectRenderingSystem(ModelBatch batch) {
|
||||
super(Aspect.getAspectForAll(ShaderComponent.class, RenderModelComponent.class, EnvironmentComponent.class).exclude(MarkerCodeComponent.class));
|
||||
|
||||
camera = null;
|
||||
this.batch = batch;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Get the necessary components.
|
||||
renderModelComponent = modelMapper.get(e);
|
||||
shaderComponent = shaderMapper.get(e);
|
||||
environment = environmentMapper.get(e);
|
||||
|
||||
// Render this entity.
|
||||
batch.render(renderModelComponent.instance, environment.environment, shaderComponent.shader);
|
||||
}
|
||||
}
|
51
src/ve/ucv/ciens/ccg/nxtar/systems/PlayerSystemBase.java
Normal file
51
src/ve/ucv/ciens/ccg/nxtar/systems/PlayerSystemBase.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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;
|
||||
private static final float MAX_Z = -4.5f;
|
||||
private 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;
|
||||
}
|
||||
}
|
@@ -18,26 +18,31 @@ package ve.ucv.ciens.ccg.nxtar.utils;
|
||||
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||
|
||||
public abstract class ProjectConstants{
|
||||
public static final int SERVICE_DISCOVERY_PORT = 9988;
|
||||
public static final int VIDEO_STREAMING_PORT = 9989;
|
||||
public static final int MOTOR_CONTROL_PORT = 9990;
|
||||
public static final int SENSOR_REPORT_PORT = 9991;
|
||||
public static final int APP_CONTROL_PORT = 9992;
|
||||
public static final int SERVICE_DISCOVERY_PORT = 9988;
|
||||
public static final int VIDEO_STREAMING_PORT = 9989;
|
||||
public static final int MOTOR_CONTROL_PORT = 9990;
|
||||
public static final int SENSOR_REPORT_PORT = 9991;
|
||||
public static final int APP_CONTROL_PORT = 9992;
|
||||
public static final String MULTICAST_ADDRESS = "230.0.0.1";
|
||||
|
||||
public static final String MULTICAST_ADDRESS = "230.0.0.1";
|
||||
public static final int EXIT_SUCCESS = 0;
|
||||
public static final int EXIT_FAILURE = 1;
|
||||
|
||||
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 int[] POWERS_OF_2 = {64, 128, 256, 512, 1024, 2048};
|
||||
public static final float OVERSCAN;
|
||||
public static final int MENU_BUTTON_FONT_SIZE;
|
||||
public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890:,";
|
||||
|
||||
public static final float OVERSCAN;
|
||||
|
||||
public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||
public static final int MAXIMUM_NUMBER_OF_MARKERS = 5;
|
||||
public static final int CALIBRATION_PATTERN_POINTS = 54;
|
||||
public static final int CALIBRATION_SAMPLES = 10;
|
||||
|
||||
static{
|
||||
OVERSCAN = Ouya.runningOnOuya ? 0.9f : 1.0f;
|
||||
MENU_BUTTON_FONT_SIZE = Ouya.runningOnOuya ? 60 : 40;
|
||||
}
|
||||
}
|
||||
|
87
src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java
Normal file
87
src/ve/ucv/ciens/ccg/nxtar/utils/Utils.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user