package cz.cuni.mff.abacs.burglar.visual;
import com.aem.sticky.StickyListener;
import com.aem.sticky.button.Button;
import com.aem.sticky.button.TextButton;
import com.aem.sticky.button.events.ClickListener;
import cz.cuni.mff.abacs.burglar.visual.play_state.PlayState;
import java.io.File;
import java.util.*;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
/**
* Game state enabling to select a level.
*
* @author abacs
*
*/
public class LevelSelectionState extends BasicGameState {
// -------------------------------------------------------------------------
/** File extension of the level files. */
private static final String MAP_EXTENSION = ".xml";
/** Width of the buttons in pixels. */
public static final int BUTTON_WIDTH = 100;
/** Height of the buttons in pixels. */
public static final int BUTTON_HEIGHT = 21;
protected static String STR_BACK = "Back";
/** Button sound. */
protected static String SUBPATH_CLICK_SOUND = "click.ogg";
// -------------------------------------------------------------------------
/** State identifier. */
private final int _stateID;
protected StickyListener _buttonListener;
/** Buttons representing the levels. */
protected List<Button> _levelButtons = new LinkedList<Button>();
/** Remembers which map to open on each button. */
protected Map<Button, String> _buttonsToFiles =
new LinkedHashMap<Button, String>();
/** Back to the MenuState button. */
protected Button _backButton;
/** Parent object. */
protected GameContainer _container = null;
/** Parent object. */
protected StateBasedGame _stateBasedGame = null;
// -------------------------------------------------------------------------
// constructors:
/**
*
*
* @param stateId
*/
public LevelSelectionState(int stateId) {
this._stateID = stateId;
}
// -------------------------------------------------------------------------
// BasigGameState:
@Override
public int getID() {
return this._stateID;
}
/**
* Initialize any needed data before the menu loop.
*
* @param container
* @param game
* @throws SlickExpression
*/
@Override
public void init(GameContainer container, StateBasedGame game)
throws SlickException {
this._stateBasedGame = game;
this._container = container;
Sound buttonSound = new Sound(VisualBurglar.PATH_SOUNDS + SUBPATH_CLICK_SOUND);
// buttons:
this._buttonListener = new StickyListener();
this.createLevelButtons(container, buttonSound);
this.createBackButton(container, buttonSound);
}
/**
* Adds listeners.
*/
@Override
public void enter(GameContainer container, StateBasedGame game) throws SlickException {
super.enter(container, game);
container.getInput().addListener(this._buttonListener);
System.out.println("Level selection state entered");
}
/**
* Removes all listeners.
*/
@Override
public void leave(GameContainer container, StateBasedGame game) throws SlickException {
super.leave(container, game);
container.getInput().removeListener(_buttonListener);
System.out.println("Level selection state left");
}
/**
* Called during the game to update the logic in our world,
* within this method we obtain the user input,
* calculate the world response to the input, do the calculation.
*
* @param container
* @param game
* @param delta
* @throws SlickExpression
*/
@Override
public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException {
for(Button button : this._levelButtons)
button.update(container, delta);
this._backButton.update(container, delta);
}
/**
* Allows to draw the menu.
*
* @param container
* @param game
* @param delta
* @throws SlickExpression
*/
@Override
public void render(
GameContainer container,
StateBasedGame game,
Graphics graphics
) throws SlickException {
// Draw menu
for(Button button : this._levelButtons)
button.render(container, graphics);
this._backButton.render(container, graphics);
}
// -------------------------------------------------------------------------
// buttons:
/** Returns with the names of the levels. */
private List<String> getLevelNames() {
List<String> result = new ArrayList<String>();
File dir = new File(VisualBurglar.PATH_MAPS);
final String[] chld = dir.list();
if(chld == null){
return result;
}
int extension_length = MAP_EXTENSION.length();
for(String str : chld){
if(str.endsWith(MAP_EXTENSION)){
result.add(str.substring(0, str.length() - extension_length));
}
}
// sort the names:
Collections.sort(result);
return result;
}
/**
* Generates the buttons.
*
* @param container
* @param buttonSound
* @throws SlickException
*/
protected void createLevelButtons(
final GameContainer container,
Sound buttonSound
) throws SlickException {
float x = 10;
float y = 10;
List<String> levelNames = this.getLevelNames();
for(int i = 0; i < levelNames.size(); i++){
TextButton button = new TextButton(
x,
y + i * (BUTTON_HEIGHT + 4),
levelNames.get(i),
buttonSound
);
this._buttonListener.add(button);
this._levelButtons.add(button);
this._buttonsToFiles.put(button, levelNames.get(i));
button.addListener(new ClickListener() {
@Override
public void onClick(
com.aem.sticky.button.Button arg0,
float arg1,
float arg2
) {
// load the map:
PlayState playState =
(PlayState)_stateBasedGame.getState(VisualBurglar.STATE_PLAY);
playState.load(
VisualBurglar.PATH_MAPS +
_buttonsToFiles.get(arg0) +
MAP_EXTENSION);
// enters the new game state:
_stateBasedGame.enterState(VisualBurglar.STATE_PLAY);
}
/** Does nothing */
@Override
public void onDoubleClick(Button arg0, float arg1, float arg2) { }
/** Does nothing */
@Override
public void onRightClick(Button arg0, float arg1, float arg2) { }
});
}
}
/**
* Back button.
*
* @param container
* @param buttonSound
* @throws SlickException
*/
protected void createBackButton(GameContainer container, Sound buttonSound)
throws SlickException {
TextButton button = new TextButton(
10,
10 + (this._levelButtons.size()) * (BUTTON_HEIGHT + 2),
STR_BACK,
buttonSound
);
this._buttonListener.add(button);
this._backButton = button;
button.addListener(new ClickListener() {
@Override
public void onClick(Button arg0, float arg1, float arg2) {
// enters the menu state:
_stateBasedGame.enterState(VisualBurglar.STATE_MENU);
}
/** Does nothing */
@Override
public void onDoubleClick(Button arg0, float arg1, float arg2) { }
/** Does nothing */
@Override
public void onRightClick(Button arg0, float arg1, float arg2) { }
});
}
}