crashtest/src/de/ctdo/crashtest/game/Statemachine.java

241 lines
6.5 KiB
Java

package de.ctdo.crashtest.game;
import de.ctdo.crashtest.log.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class Statemachine implements IStatemachine {
public enum state {
IDLE,
ENTERED_ROOM,
TABLE_GAME_ONE,
TABLE_GAME_TWO,
TABLE_GAME_THREE,
TABLE_GAME_FOUR,
TABLE_GAME_FIVE,
TABLE_GAME_SIX,
TABLE_GAME_DONE,
ROKET_STARTED,
ROKET_DONE
}
private final char RESET = '1';
private final char BLUE_BUTTON = 'E';
private final char LIGHT_BARRIER = 'F';
private final char TABLE_ONE = 'G';
private final char TABLE_TWO = 'H';
private final char TABLE_THREE = 'I';
private final char ROKET_INPUT = 'B';
private final List<StatemachineListener> statemachineListenerList;
private Timer timer;
private long lastHandleInput;
private int stateChangeCounter;
private state currentState;
private int timertSecondsLast;
public Statemachine() {
currentState = state.IDLE;
statemachineListenerList = new ArrayList<StatemachineListener>();
}
@Override
public void addListener(StatemachineListener listener) {
statemachineListenerList.add(listener);
}
@Override
public state getCurrentState() {
return currentState;
}
@Override
public void setNewState(state newState) {
currentState = newState;
stateChangeCounter++;
onStateChanged();
}
@Override
public int getStateChangeCounter() {
return stateChangeCounter;
}
@Override
public void reset() {
stateChangeCounter = 0;
currentState = state.IDLE;
stopTimer();
onStateChanged();
}
@Override
public void handleInput(char input) {
if(System.currentTimeMillis() - lastHandleInput < 200 ) return;
state newState = getNewState(input);
if( newState != currentState ) {
stateChangeCounter++;
Logger.sLog("newState = " + newState);
currentState = newState;
onStateChanged();
}
lastHandleInput = System.currentTimeMillis();
}
@Override
public int getTimerSecondsLast() {
return timertSecondsLast / 10;
}
@Override
public void startTimer(int seconds) {
Logger.sLog("starting timer");
timertSecondsLast = seconds*10;
scheduleTimer();
}
@Override
public void stopTimer() {
Logger.sLog("stopping timer");
if(timer != null) timer.cancel();
timertSecondsLast = 0;
}
@Override
public void pauseTimer(boolean pause) {
Logger.sLog("pausing timer: " + pause);
if(pause) {
if(timer != null) timer.cancel();
} else {
scheduleTimer();
}
}
/**
* notifies all listeners about the changed state
*/
private void onStateChanged() {
for(StatemachineListener listener: statemachineListenerList) {
listener.stateChanged(currentState);
}
}
private void onTimerTick() {
for(StatemachineListener listener: statemachineListenerList) {
listener.timerTick(timertSecondsLast);
}
}
/**
* Calculates the new game state from the current state and new input button
* @param input the char from the input
* @return returns the new state
*/
private state getNewState(char input) {
state retVal = currentState;
if(input == RESET) {
retVal = state.IDLE;
} else {
switch (currentState) {
case IDLE:
if(input == LIGHT_BARRIER) {
retVal = state.ENTERED_ROOM;
}
break;
case ENTERED_ROOM:
if(input == TABLE_ONE) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_ONE:
if(input == TABLE_TWO) {
retVal = state.TABLE_GAME_TWO;
}
break;
case TABLE_GAME_TWO:
if(input == TABLE_THREE) {
retVal = state.TABLE_GAME_THREE;
} else if (input == TABLE_ONE) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_THREE:
if(input == TABLE_TWO) {
retVal = state.TABLE_GAME_FOUR;
} else if (input == TABLE_ONE) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_FOUR:
if(input == TABLE_THREE) {
retVal = state.TABLE_GAME_FIVE;
} else if (input == TABLE_ONE) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_FIVE:
if(input == TABLE_ONE) {
retVal = state.TABLE_GAME_SIX;
} else if (input == TABLE_TWO) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_SIX:
if(input == TABLE_THREE) {
retVal = state.TABLE_GAME_DONE;
} else if (input == TABLE_TWO) {
retVal = state.TABLE_GAME_ONE;
}
break;
case TABLE_GAME_DONE:
if(input == BLUE_BUTTON) {
retVal = state.ROKET_STARTED;
}
break;
case ROKET_STARTED:
if(input == ROKET_INPUT) {
retVal = state.ROKET_DONE;
}
}
}
return retVal;
}
private void scheduleTimer() {
if(timer != null) timer.cancel();
timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
timertSecondsLast--;
onTimerTick();
if(timertSecondsLast <= 0) {
if(timer != null) timer.cancel();
}
}
};
timer.scheduleAtFixedRate(timerTask, 100, 100);
}
}