package com.shade.states; import java.util.ArrayList; import java.util.Scanner; import org.newdawn.slick.Color; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.Image; import org.newdawn.slick.Input; import org.newdawn.slick.SlickException; import org.newdawn.slick.Sound; import org.newdawn.slick.TrueTypeFont; import org.newdawn.slick.state.BasicGameState; import org.newdawn.slick.state.StateBasedGame; import org.newdawn.slick.util.ResourceLoader; import com.shade.base.Animatable; import com.shade.controls.Button; import com.shade.controls.ClickListener; import com.shade.controls.InstructionImage; import com.shade.controls.InstructionText; import com.shade.controls.KeyListener; import com.shade.controls.SerialStats; import com.shade.controls.SlickButton; import com.shade.controls.TwoToneButton; import com.shade.levels.LevelManager; import com.shade.util.ResourceManager; public class SelectState extends BasicGameState { public static final int ID = 10; private static final int LEVEL_STATE_DELAY = 600; private static final int LEVEL_BUFFER = 5000; private MasterState master; private InGameState level; private LevelManager manager; private ResourceManager resource; private SlickButton play, back; private TwoToneButton next, prev; private LevelSet levels; int currentLevel; private int timer; private Sound click; private StateBasedGame game; @Override public int getID() { return ID; } public SelectState(MasterState m) throws SlickException { master = m; resource = m.resource; resource.register("newgame-up", "states/select/newgame-up.png"); resource.register("newgame-down", "states/select/newgame-down.png"); resource.register("question-mark", "states/select/question-mark.png"); resource.register("crown", "states/highscore/crown.png"); click = new Sound("states/common/click.ogg"); manager = new LevelManager(); } public void init(GameContainer container, StateBasedGame game) throws SlickException { throw new RuntimeException("SelectState was init'd!"); } public void enter(GameContainer container, final StateBasedGame game) throws SlickException { this.game = game; level = (InGameState) game.getState(InGameState.ID); currentLevel = level.getCurrentLevel(); initLevels(master.jekyllMedium); if (master.dimmer.reversed()) { master.dimmer.rewind(); } initFlowButtons(); initButtons(); timer = 0; } public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException { master.control.render(game, g, resource.get("background")); g.setColor(Color.black); if (!master.levelsLock.isUnlocked(currentLevel)) { g.fillRect(0, 0, 800, 600); } g.setColor(Color.white); master.dimmer.render(game, g); resource.get("header").draw(400, 0); resource.get("backdrop").draw(0, 400); play.render(game, g); back.render(game, g); prev.render(game, g); next.render(game, g); renderInstructionStep(); if (!master.levelsLock.isUnlocked(currentLevel)) { resource.get("question-mark").draw(310, 160); } if (currentLevel > 0 && SerialStats.read("level-" + currentLevel + "-clear") == 1) { resource.get("crown").draw(15, 412); } levels.render(game, g); resource.get("trim").draw(); } private void renderInstructionStep() { master.jekyllXSmall.drawString(18, 495, (1 + currentLevel) + " of " + levels.size()); } public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException { master.control.update(game, delta); master.dimmer.update(game, delta); resource.get("backdrop").draw(0, 400); timer += delta; if (timer > MasterState.STATE_TRANSITION_DELAY) { play.update(game, delta); back.update(game, delta); prev.update(game, delta); next.update(game, delta); } prev.active(levels.started()); next.active(levels.finished()); levels.update(game, delta); } @Override public void keyPressed(int key, char c) { if (key == Input.KEY_ENTER) { click.play(); if (!master.levelsLock.isUnlocked(currentLevel)) { return; } level.newGame(currentLevel); if (currentLevel == 0) { game.enterState(InstructionState.ID); } else { game.enterState(InGameState.ID); } } } private void initButtons() throws SlickException { initPlayButton(); initBackButton(); } private void initPlayButton() throws SlickException { play = new SlickButton(620, 110, resource.get("play-up"), resource .get("play-down")); play.addListener(new ClickListener() { public void onClick(StateBasedGame game, Button clicked) { if (!master.levelsLock.isUnlocked(currentLevel)) { return; } level.newGame(currentLevel); if (currentLevel == 0) { game.enterState(InstructionState.ID); } else { game.enterState(InGameState.ID); } } }); } private void initBackButton() throws SlickException { back = new SlickButton(620, 130, resource.get("back-up"), resource .get("back-down")); back.addListener(new ClickListener() { public void onClick(StateBasedGame game, Button clicked) { game.enterState(TitleState.ID); master.dimmer.reverse(); } }); } private void initFlowButtons() throws SlickException { Image up = resource.get("next-up"); Image down = resource.get("next-down"); next = new TwoToneButton(760, 490, up, down); prev = new TwoToneButton(740, 490, up.getFlippedCopy(true, false), down .getFlippedCopy(true, false)); next.addListener(new ClickListener() { public void onClick(StateBasedGame game, Button clicked) { currentLevel++; levels.next(); master.control.load(manager.get(currentLevel)); master.control.killPlayer(); } }); next.register(Input.KEY_RIGHT, new KeyListener() { public void onPress(StateBasedGame game, int key) { currentLevel++; levels.next(); master.control.load(manager.get(currentLevel)); master.control.killPlayer(); } }); prev.addListener(new ClickListener() { public void onClick(StateBasedGame game, Button clicked) { currentLevel--; levels.prev(); master.control.load(manager.get(currentLevel)); master.control.killPlayer(); } }); prev.register(Input.KEY_LEFT, new KeyListener() { public void onPress(StateBasedGame game, int key) { currentLevel--; levels.prev(); master.control.load(manager.get(currentLevel)); master.control.killPlayer(); } }); } private void initLevels(TrueTypeFont f) throws SlickException { Scanner hints = new Scanner(ResourceLoader .getResourceAsStream("states/select/hints.txt")); Image locked = new Image("states/select/locked.png"); Scanner names = new Scanner(ResourceLoader .getResourceAsStream("states/select/levels.txt")); Image unlocked = new Image("states/select/unlocked.png"); levels = new LevelSet(); float x = 90; int n = 0; while (hints.hasNextLine()) { InstructionImage i = null; InstructionText t = null; if (master.levelsLock.isUnlocked(n)) { i = new InstructionImage(x, 425, unlocked); i.setTimer(LEVEL_STATE_DELAY + n * LEVEL_BUFFER); t = new InstructionText(x + 100, 445, names.nextLine(), f); t.setTimer(LEVEL_STATE_DELAY + n * LEVEL_BUFFER); hints.nextLine(); } else { i = new InstructionImage(x - 6, 425 + 11, locked); i.setTimer(LEVEL_STATE_DELAY + n * LEVEL_BUFFER); t = new InstructionText(x + 100, 445, hints.nextLine(), f); t.setTimer(LEVEL_STATE_DELAY + n * LEVEL_BUFFER); names.nextLine(); } levels.add(i, t); n++; } } private class LevelSet implements Animatable { private boolean finished; private ArrayList<InstructionImage> images; private ArrayList<InstructionText> text; public LevelSet() { images = new ArrayList<InstructionImage>(); text = new ArrayList<InstructionText>(); finished = (currentLevel == LevelManager.NUM_LEVELS - 1); } public void moveTo(int level) { currentLevel = level; for (int i = 0; i < text.size(); i++) { if (i == level) { images.get(i).activate(); text.get(i).activate(); } else { images.get(i).deactivate(); text.get(i).deactivate(); } } } public int current() { return currentLevel + 1; } public int size() { return text.size(); } public void add(InstructionImage i, InstructionText t) { if (text.size() == currentLevel) { t.activate(); i.activate(); } images.add(i); text.add(t); } public void next() { int last = currentLevel - 1; text.get(last).deactivate(); images.get(last).deactivate(); if (currentLevel < text.size()) { text.get(currentLevel).activate(); images.get(currentLevel).activate(); if (currentLevel == text.size() - 1) { finished = true; } } } public void prev() { int last = currentLevel + 1; text.get(last).deactivate(); images.get(last).deactivate(); text.get(currentLevel).activate(); images.get(currentLevel).activate(); if (finished) { finished = false; } } public void reset(int last) { images.get(last).reset(); text.get(last).reset(); images.get(currentLevel).activate(); text.get(currentLevel).activate(); } public void render(StateBasedGame game, Graphics g) { for (InstructionText s : text) { s.render(game, g); } for (InstructionImage i : images) { i.render(game, g); } } public void update(StateBasedGame game, int delta) { for (InstructionText s : text) { s.update(game, delta); } for (InstructionImage i : images) { i.update(game, delta); } } public boolean started() { return currentLevel == 0; } public boolean finished() { return finished; } } }