All bombs sucessfully implemented.

This commit is contained in:
2014-06-17 17:57:57 -04:30
parent 29c4bea104
commit 8bd799f146
9 changed files with 441 additions and 62 deletions

View File

@@ -394,6 +394,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
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);
}batch.end();
}
}

View File

@@ -28,6 +28,7 @@ public class BombGameObjectTypeComponent extends Component {
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;

View File

@@ -0,0 +1,72 @@
/*
* 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;
public class FadeEffectComponent extends Component{
private MutableFloat alpha;
private Tween fadeIn;
private Tween fadeOut;
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;
}
}
public float getFloatValue(){
return alpha.floatValue();
}
public void update(float delta){
if(fadeIn != null)
fadeIn.update(delta);
if(fadeOut != null)
fadeOut.update(delta);
}
public void startEffect(){
if(fadeIn != null)
fadeIn.start();
if(fadeOut != null)
fadeOut.start();
}
public boolean isEffectStarted(){
return fadeIn != null ? fadeIn.isStarted() : fadeOut.isStarted();
}
public boolean isEffectFadeIn(){
return fadeIn != null;
}
public boolean isEffectFinished(){
return fadeIn != null ? fadeIn.isFinished() : fadeOut.isFinished();
}
}

View File

@@ -56,7 +56,7 @@ public class BombGameEntityCreator extends EntityCreatorBase{
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 = 1;
public static final int DOOR_CLOSE_ANIMATION = 0;
private class EntityParameters{
public Environment environment;

View File

@@ -29,6 +29,7 @@ import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue;
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
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.GeometrySystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem;
@@ -61,6 +62,7 @@ public class InGameState extends BaseState{
private static final String TAG = "IN_GAME_STATE";
private static final String CLASS_NAME = InGameState.class.getSimpleName();
private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg";
private static final String ALPHA_SHADER_PREFIX = "shaders/alphaSprite/alpha";
private static final float NEAR = 0.01f;
private static final float FAR = 100.0f;
@@ -91,12 +93,16 @@ public class InGameState extends BaseState{
private ModelBatch modelBatch;
private FrameBuffer frameBuffer;
private Sprite frameBufferSprite;
private FrameBuffer robotArmFrameBuffer;
private Sprite robotArmFrameBufferSprite;
private ShaderProgram alphaShader;
// Game related fields.
private World gameWorld;
private MarkerRenderingSystem markerRenderingSystem;
private ObjectRenderingSystem objectRenderingSystem;
private RobotArmPositioningSystem robotArmPositioningSystem;
private FadeEffectRenderingSystem fadeEffectRenderingSystem;
private robot_control_mode_t controlMode;
// Cameras.
@@ -114,6 +120,8 @@ public class InGameState extends BaseState{
private Texture headControlButtonTexture;
private Texture wheelControlButtonTexture;
private Texture armControlButtonTexture;
private Texture correctAngleLedOnTexture;
private Texture correctAngleLedOffTexture;
private Sprite motorAButton;
private Sprite motorBButton;
private Sprite motorCButton;
@@ -123,6 +131,8 @@ public class InGameState extends BaseState{
private Sprite headCButton;
private Sprite wheelControlButton;
private Sprite armControlButton;
private Sprite correctAngleLedOnSprite;
private Sprite correctAngleLedOffSprite;
// Button touch helper fields.
private boolean[] buttonsTouched;
@@ -192,7 +202,7 @@ public class InGameState extends BaseState{
// 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 + ".MainMenuStateBase() :: Failed to compile the background shader.");
Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the background shader.");
Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog());
backgroundShader = null;
}
@@ -201,11 +211,21 @@ public class InGameState extends BaseState{
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 alpha shader.
alphaShader = new ShaderProgram(Gdx.files.internal(ALPHA_SHADER_PREFIX + "_vert.glsl"), Gdx.files.internal(ALPHA_SHADER_PREFIX + "_frag.glsl"));
if(!alphaShader.isCompiled()){
Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the alpha shader.");
Gdx.app.error(TAG, CLASS_NAME + alphaShader.getLog());
alphaShader = null;
}
// Set up the 3D rendering.
modelBatch = new ModelBatch();
frameBuffer = null;
perspectiveCamera = null;
frameBufferSprite = null;
robotArmFrameBuffer = null;
robotArmFrameBufferSprite = null;
// Set up the game world.
gameWorld = GameSettings.getGameWorld();
@@ -213,6 +233,7 @@ public class InGameState extends BaseState{
robotArmPositioningSystem = new RobotArmPositioningSystem();
markerRenderingSystem = new MarkerRenderingSystem(modelBatch);
objectRenderingSystem = new ObjectRenderingSystem(modelBatch);
fadeEffectRenderingSystem = new FadeEffectRenderingSystem();
gameWorld.setSystem(new MarkerPositioningSystem());
gameWorld.setSystem(robotArmPositioningSystem, Ouya.runningOnOuya);
@@ -222,6 +243,7 @@ public class InGameState extends BaseState{
gameWorld.setSystem(GameSettings.getGameLogicSystem());
gameWorld.setSystem(markerRenderingSystem, true);
gameWorld.setSystem(objectRenderingSystem, true);
gameWorld.setSystem(fadeEffectRenderingSystem, true);
gameWorld.initialize();
}
@@ -263,6 +285,9 @@ public class InGameState extends BaseState{
frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
robotArmFrameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
robotArmFrameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
perspectiveCamera = new CustomPerspectiveCamera(67, w, h);
perspectiveCamera.translate(0.0f, 0.0f, 0.0f);
perspectiveCamera.near = NEAR;
@@ -315,12 +340,19 @@ public class InGameState extends BaseState{
markerRenderingSystem.begin(perspectiveCamera);
markerRenderingSystem.process();
markerRenderingSystem.end();
}frameBuffer.end();
robotArmFrameBuffer.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.
objectRenderingSystem.begin(perspectiveCamera);
objectRenderingSystem.process();
objectRenderingSystem.end();
}frameBuffer.end();
}robotArmFrameBuffer.end();
// Set the frame buffer object texture to a renderable sprite.
region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
@@ -332,6 +364,16 @@ public class InGameState extends BaseState{
frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2);
frameBufferSprite.setPosition(0, 0);
// Set the other frame buffer object texture to a renderable sprite.
region = new TextureRegion(robotArmFrameBuffer.getColorBufferTexture(), 0, 0, robotArmFrameBuffer.getWidth(), robotArmFrameBuffer.getHeight());
region.flip(false, true);
if(robotArmFrameBufferSprite == null)
robotArmFrameBufferSprite = new Sprite(region);
else
robotArmFrameBufferSprite.setRegion(region);
robotArmFrameBufferSprite.setOrigin(robotArmFrameBuffer.getWidth() / 2, robotArmFrameBuffer.getHeight() / 2);
robotArmFrameBufferSprite.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() );
@@ -341,6 +383,10 @@ public class InGameState extends BaseState{
frameBufferSprite.setSize(1.0f, frameBufferSprite.getHeight() / frameBufferSprite.getWidth() );
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight());
robotArmFrameBufferSprite.setSize(1.0f, robotArmFrameBufferSprite.getHeight() / robotArmFrameBufferSprite.getWidth() );
robotArmFrameBufferSprite.rotate90(true);
robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, 0.5f - robotArmFrameBufferSprite.getHeight());
}else{
float xSize = Gdx.graphics.getHeight() * (w / h);
renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
@@ -350,6 +396,10 @@ public class InGameState extends BaseState{
frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2);
robotArmFrameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
robotArmFrameBufferSprite.rotate90(true);
robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, -robotArmFrameBufferSprite.getHeight() / 2);
}
// Set the correct camera for the device.
@@ -363,6 +413,13 @@ public class InGameState extends BaseState{
core.batch.begin();{
renderableVideoFrame.draw(core.batch);
frameBufferSprite.draw(core.batch);
if(alphaShader != null){
core.batch.setShader(alphaShader);
}
robotArmFrameBufferSprite.draw(core.batch);
if(alphaShader != null) core.batch.setShader(null);
}core.batch.end();
// Clear the video frame from memory.
@@ -389,9 +446,16 @@ public class InGameState extends BaseState{
throw new IllegalStateException("Unrecognized control mode: " + Integer.toString(controlMode.getValue()));
}
if(Math.abs(Gdx.input.getRoll()) < ProjectConstants.MAX_ABS_ROLL){
correctAngleLedOnSprite.draw(core.batch);
}else{
correctAngleLedOffSprite.draw(core.batch);
}
}core.batch.end();
}
fadeEffectRenderingSystem.process();
data = null;
}
@@ -421,8 +485,22 @@ public class InGameState extends BaseState{
if(backgroundShader != null)
backgroundShader.dispose();
if(alphaShader != null)
alphaShader.dispose();
if(frameBuffer != null)
frameBuffer.dispose();
if(robotArmFrameBuffer != null)
robotArmFrameBuffer.dispose();
if(correctAngleLedOffTexture != null)
correctAngleLedOffTexture.dispose();
if(correctAngleLedOnTexture != null)
correctAngleLedOnTexture.dispose();
fadeEffectRenderingSystem.dispose();
}
/*;;;;;;;;;;;;;;;;;;
@@ -454,10 +532,13 @@ public class InGameState extends BaseState{
motorAButton = new Sprite(region);
motorAButton.setSize(motorAButton.getWidth() * 0.7f, motorAButton.getHeight() * 0.7f);
motorBButton = new Sprite(region);
motorBButton.setSize(motorBButton.getWidth() * 0.7f, motorBButton.getHeight() * 0.7f);
motorCButton = new Sprite(region);
motorCButton.setSize(motorCButton.getWidth() * 0.7f, motorCButton.getHeight() * 0.7f);
motorDButton = new Sprite(region);
motorDButton.setSize(motorDButton.getWidth() * 0.7f, motorDButton.getHeight() * 0.7f);
@@ -487,11 +568,25 @@ public class InGameState extends BaseState{
wheelControlButton = new Sprite(wheelControlButtonTexture);
wheelControlButton.setSize(wheelControlButton.getWidth() * 0.3f, wheelControlButton.getHeight() * 0.3f);
armControlButton = new Sprite(armControlButtonTexture);
armControlButton.setSize(armControlButton.getWidth() * 0.3f, armControlButton.getHeight() * 0.3f);
wheelControlButton.setPosition(-(wheelControlButton.getWidth() / 2), headCButton.getY() - headCButton.getHeight() - 15);
armControlButton.setPosition(-(armControlButton.getWidth() / 2), headCButton.getY() - headCButton.getHeight() - 15);
// Set up the correct angle leds.
correctAngleLedOnTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Green.png"));
correctAngleLedOffTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Red.png"));
correctAngleLedOnSprite = new Sprite(correctAngleLedOnTexture);
correctAngleLedOffSprite = new Sprite(correctAngleLedOffTexture);
correctAngleLedOnSprite.setSize(correctAngleLedOnSprite.getWidth() * 0.25f, correctAngleLedOnSprite.getHeight() * 0.25f);
correctAngleLedOffSprite.setSize(correctAngleLedOffSprite.getWidth() * 0.25f, correctAngleLedOffSprite.getHeight() * 0.25f);
correctAngleLedOnSprite.setPosition(Gdx.graphics.getWidth() / 2 - correctAngleLedOnSprite.getWidth() - 5, Gdx.graphics.getHeight() / 2 - correctAngleLedOnSprite.getHeight() - 5);
correctAngleLedOffSprite.setPosition(Gdx.graphics.getWidth() / 2 - correctAngleLedOffSprite.getWidth() - 5, Gdx.graphics.getHeight() / 2 - correctAngleLedOffSprite.getHeight() - 5);
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@@ -18,42 +18,66 @@ package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.components.AnimationComponent;
import ve.ucv.ciens.ccg.nxtar.components.BombGameObjectTypeComponent;
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.VisibilityComponent;
import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
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;
import com.badlogic.gdx.Input.Peripheral;
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<BombGameObjectTypeComponent> 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 BombGameObjectTypeComponent tempType;
private GroupManager manager;
private int then;
@SuppressWarnings("unchecked")
public BombGameLogicSystem(){
super(Aspect.getAspectForAll(BombGameObjectTypeComponent.class));
manager = world.getManager(GroupManager.class);
manager = null;
then = 0;
}
@Override
protected void process(Entity e){
BombGameObjectTypeComponent typeComponent;
if(manager == null)
manager = world.getManager(GroupManager.class);
typeComponent = typeMapper.get(e);
switch(typeComponent.type){
@@ -78,6 +102,10 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
processDoor(e);
break;
case BombGameObjectTypeComponent.FADE_EFFECT:
processFade(e);
break;
default:
break;
}
@@ -89,11 +117,9 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
* @param b An Artemis {@link Entity} that possibly represents any of a Wire Bomb's wires.
*/
private void processWireBomb(Entity b){
int relatedWires = 0;
CollisionDetectionComponent collision;
MarkerCodeComponent marker;
BombGameObjectTypeComponent wireType;
ImmutableBag<Entity> related;
// Get this wire's parameters.
collision = collisionMapper.getSafe(b);
@@ -107,27 +133,22 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
}
// 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();
related = manager.getEntities(Integer.toString(marker.code));
// Check the state of the other wires 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 >= BombGameObjectTypeComponent.BOMB_WIRE_1 && tempType.type <= BombGameObjectTypeComponent.BOMB_WIRE_3){
if(tempType.type != wireType.type){
relatedWires++;
}
}
if(wireType.type != BombGameObjectTypeComponent.BOMB_WIRE_1){
Gdx.app.log(TAG, CLASS_NAME + ".processWireBomb(): Wire bomb exploded.");
createFadeOutEffect();
}
if(relatedWires == 0)
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());
}
}
@@ -137,11 +158,10 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
* @param b An Artemis {@link Entity} that possibly represents any of a Combination Bomb's buttons.
*/
private void processCombinationBomb(Entity b){
int relatedButtons = 0;
combination_button_state_t state;
CollisionDetectionComponent collision;
MarkerCodeComponent marker;
BombGameObjectTypeComponent buttonType;
ImmutableBag<Entity> related;
// Get this wire's parameters.
collision = collisionMapper.getSafe(b);
@@ -155,27 +175,27 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
}
// 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();
related = manager.getEntities(Integer.toString(marker.code));
// Check the state of the other wires associated with this bomb.
for(int i = 0; i < related.size(); i++){
tempType = typeMapper.getSafe(related.get(i));
// Check the state of the other buttons associated with this bomb.
if(tempType == null) continue;
state = checkCombinationBombButtons(buttonType.type, marker.code);
if(tempType.type >= BombGameObjectTypeComponent.COM_BUTTON_1 && tempType.type <= BombGameObjectTypeComponent.COM_BUTTON_4){
if(tempType.type != buttonType.type){
relatedButtons++;
}
}
}
if(relatedButtons == 0)
if(state.getValue() == combination_button_state_t.INCORRECT.getValue()){
Gdx.app.log(TAG, CLASS_NAME + ".processCombinationBomb(): Combination bomb exploded.");
createFadeOutEffect();
disableBomb(marker.code);
}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());
}
}
@@ -188,6 +208,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
// Get the components of the big button.
CollisionDetectionComponent collision = collisionMapper.getSafe(b);
MarkerCodeComponent marker = markerMapper.getSafe(b);
float angle;
// If any of the components is missing, skip this entity.
if(marker == null || collision == null ){
@@ -196,6 +217,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
}
// 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;
@@ -203,11 +225,22 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
manager.remove(b, Integer.toString(marker.code));
b.deleteFromWorld();
angle = Gdx.input.getRoll();
Gdx.app.log("ROTATION", "Roll: " + Float.toString(angle));
if(Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer) && Math.abs(angle) > ProjectConstants.MAX_ABS_ROLL){
Gdx.app.log(TAG, CLASS_NAME + ".processInclinationBomb(): Inclination bomb exploded.");
createFadeOutEffect();
}
// 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());
}
}
/**
@@ -241,7 +274,7 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
}
}else{
// If the door is disabled and open, then set it's closing animation.
if(animation.current != 0){
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.");
@@ -256,12 +289,16 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
* @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){
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));
@@ -283,10 +320,14 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
* <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){
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));
@@ -295,14 +336,124 @@ public class BombGameLogicSystem extends GameLogicSystemBase {
// Enable collisions with the corresponding door frame entity. Disable collisions with other related entities.
if(tempMarker != null) tempMarker.enabled = false;
if(tempType != null){
if(tempType.type != BombGameObjectTypeComponent.DOOR_FRAME){
if(tempType.type != BombGameObjectTypeComponent.DOOR_FRAME && tempType.type != BombGameObjectTypeComponent.DOOR){
manager.remove(related.get(i), CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
manager.remove(related.get(i), Integer.toString(markerCode));
related.get(i).deleteFromWorld();
}else{
}else if(tempType.type != BombGameObjectTypeComponent.DOOR_FRAME){
manager.add(related.get(i), CollisionDetectionSystem.COLLIDABLE_OBJECTS_GROUP);
}
}
}
}
/**
* <p>Checks if a combination bomb is being disabled in the correct sequence.</p>
*
* @param buttonType A number between {@link BombGameObjectTypeComponent.COM_BUTTON_1} and {@link BombGameObjectTypeComponent.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 < BombGameObjectTypeComponent.COM_BUTTON_1 || buttonType > BombGameObjectTypeComponent.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 >= BombGameObjectTypeComponent.COM_BUTTON_1 && tempType.type <= BombGameObjectTypeComponent.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 BombGameObjectTypeComponent(BombGameObjectTypeComponent.FADE_EFFECT));
effect.addComponent(new FadeEffectComponent(false));
effect.addToWorld();
}
/**
* <p>Adds a new fade in entity to the {@link World}.</p>
*/
private void createFadeInEffect(){
Entity effect = world.createEntity();
effect.addComponent(new BombGameObjectTypeComponent(BombGameObjectTypeComponent.FADE_EFFECT));
effect.addComponent(new FadeEffectComponent(true));
effect.addToWorld();
}
/**
* <p>Updates a fade effect entity.</p>
*
* @param f An Artemis {@link Entity} possibly referencing a fade effect.
*/
private void processFade(Entity f){
FadeEffectComponent fade = fadeMapper.getSafe(f);
if(fade != null){
if(!fade.isEffectStarted())
fade.startEffect();
if(!fade.isEffectFinished()){
// If the fade has not finished then just update it.
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Updating fade.");
fade.update(Gdx.graphics.getDeltaTime());
}else{
// If the fade finished.
if(fade.isEffectFadeIn()){
// If the effect was a fade in then just remove it.
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): deleting fade in.");
f.deleteFromWorld();
}else{
// If the effect was a fade out then wait for one second and then remove it and start a fade in.
then += (int)(Gdx.graphics.getDeltaTime() * 1000.0f);
if(then >= 1500){
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Deleting fade out.");
f.deleteFromWorld();
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Creating fade in.");
createFadeInEffect();
then = 0;
}else{
Gdx.app.log(TAG, CLASS_NAME + ".processFade(): Waiting after fade out: " + Integer.toString(then));
}
}
}
}
}
}

View File

@@ -0,0 +1,57 @@
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) {
FadeEffectComponent fade = fadeMapper.get(e);
this.batch.setProjectionMatrix(this.camera.combined);
this.batch.begin();{
this.batch.setColor(1, 1, 1, fade.getFloatValue());
this.batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
this.batch.setColor(1, 1, 1, 1);
}this.batch.end();
}
}

View File

@@ -147,6 +147,7 @@ public class RobotArmPositioningSystem extends EntityProcessingSystem {
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Going forward now.");
}else if(auto.distance >= 1.0f || collision.colliding){
auto.forward = false;
auto.startPoint.set(BombGameEntityCreator.ROBOT_ARM_START_POINT);
Gdx.app.log(TAG, CLASS_NAME + ".autoMove(): Going backwards now.");
}

View File

@@ -28,9 +28,10 @@ public abstract class ProjectConstants{
public static final int EXIT_SUCCESS = 0;
public static final int EXIT_FAILURE = 1;
public static final boolean DEBUG = true;
public static final boolean DEBUG = false;
public static final int[] POWERS_OF_2 = {64, 128, 256, 512, 1024, 2048};
public static final float MAX_ABS_ROLL = 60.0f;
public static final float OVERSCAN;
public static final int MENU_BUTTON_FONT_SIZE;