From 1fb7799ff91729285bf145b2c78f9233a61ac35c Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sun, 15 Feb 2009 14:54:15 -0500 Subject: Engine: Fixed MessageWindow bug Previously, MessageWindow would, on occasion, throw out an ArrayIndexOutOfBoundsException. This may have been because of some keyboard input. Because of this, the keyboard input system has been re-written to be anologous to the Display system (Renderable). Now, only one input processor will run at a time because they are executed in order by KeyboardInput, rather than all at once using AWT event handlers. --- src/com/fourisland/fourpuzzle/Game.java | 11 -- src/com/fourisland/fourpuzzle/KeyInput.java | 60 +++++++++++ src/com/fourisland/fourpuzzle/KeyboardInput.java | 45 ++++++++ .../fourisland/fourpuzzle/PuzzleApplication.java | 11 +- .../fourpuzzle/gamestate/GameOverGameState.java | 7 +- .../fourisland/fourpuzzle/gamestate/GameState.java | 4 +- .../fourpuzzle/gamestate/TitleScreenGameState.java | 9 +- .../gamestate/mapview/MapViewGameState.java | 115 ++++++++++----------- src/com/fourisland/fourpuzzle/util/Inputable.java | 17 +++ .../fourpuzzle/window/MessageWindow.java | 42 ++++---- 10 files changed, 211 insertions(+), 110 deletions(-) create mode 100644 src/com/fourisland/fourpuzzle/KeyInput.java create mode 100644 src/com/fourisland/fourpuzzle/KeyboardInput.java create mode 100644 src/com/fourisland/fourpuzzle/util/Inputable.java (limited to 'src') diff --git a/src/com/fourisland/fourpuzzle/Game.java b/src/com/fourisland/fourpuzzle/Game.java index 432d8ff..b3d5190 100755 --- a/src/com/fourisland/fourpuzzle/Game.java +++ b/src/com/fourisland/fourpuzzle/Game.java @@ -7,7 +7,6 @@ package com.fourisland.fourpuzzle; import com.fourisland.fourpuzzle.gamestate.mapview.event.HeroEvent; import com.fourisland.fourpuzzle.gamestate.GameState; -import java.awt.event.KeyEvent; /** * @@ -45,16 +44,6 @@ public class Game { Game.gameState.initalize(); } - private static KeyEvent key; - public static KeyEvent getKey() - { - return key; - } - public static void setKey(KeyEvent key) - { - Game.key = key; - } - public static HeroEvent getHeroEvent() { return getSaveFile().getHero(); diff --git a/src/com/fourisland/fourpuzzle/KeyInput.java b/src/com/fourisland/fourpuzzle/KeyInput.java new file mode 100644 index 0000000..37eda77 --- /dev/null +++ b/src/com/fourisland/fourpuzzle/KeyInput.java @@ -0,0 +1,60 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.fourisland.fourpuzzle; + +import java.awt.event.KeyEvent; + +/** + * + * @author hatkirby + */ +public class KeyInput +{ + private boolean ctrl = false; + private boolean alt = false; + private boolean shift = false; + private int key = 0; + public void keyInput(KeyEvent ev) + { + ctrl = ev.isControlDown(); + alt = ev.isAltDown(); + shift = ev.isShiftDown(); + key = ev.getKeyCode(); + } + + public void letGo() + { + ctrl = false; + alt = false; + shift = false; + key = 0; + } + + public boolean isCtrlDown() + { + return ctrl; + } + + public boolean isAltDown() + { + return alt; + } + + public boolean isShiftDown() + { + return shift; + } + + public boolean isKeyDown() + { + return (key == 0 ? false : true); + } + + public int getKey() + { + return key; + } +} \ No newline at end of file diff --git a/src/com/fourisland/fourpuzzle/KeyboardInput.java b/src/com/fourisland/fourpuzzle/KeyboardInput.java new file mode 100644 index 0000000..a3e849d --- /dev/null +++ b/src/com/fourisland/fourpuzzle/KeyboardInput.java @@ -0,0 +1,45 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.fourisland.fourpuzzle; + +import com.fourisland.fourpuzzle.util.Inputable; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * + * @author hatkirby + */ +public class KeyboardInput { + + private static CopyOnWriteArrayList inputables = new CopyOnWriteArrayList(); + private static KeyInput key = new KeyInput(); + + public static synchronized void registerInputable(Inputable inputable) + { + inputables.add(inputable); + } + + public static synchronized void unregisterInputable(Inputable inputable) + { + inputables.remove(inputable); + } + + public static void processInput() + { + Game.getGameState().processInput(key); + + for (Inputable inputable : inputables) + { + inputable.processInput(key); + } + } + + static synchronized KeyInput getKey() + { + return key; + } + +} \ No newline at end of file diff --git a/src/com/fourisland/fourpuzzle/PuzzleApplication.java b/src/com/fourisland/fourpuzzle/PuzzleApplication.java index cc9af03..069b126 100755 --- a/src/com/fourisland/fourpuzzle/PuzzleApplication.java +++ b/src/com/fourisland/fourpuzzle/PuzzleApplication.java @@ -7,7 +7,6 @@ package com.fourisland.fourpuzzle; import com.fourisland.fourpuzzle.database.Database; import com.fourisland.fourpuzzle.database.Vocabulary; import com.fourisland.fourpuzzle.gamestate.TitleScreenGameState; -import com.fourisland.fourpuzzle.gamestate.mapview.ChipSet; import com.fourisland.fourpuzzle.util.Interval; import com.fourisland.fourpuzzle.window.SystemGraphic; import java.awt.GraphicsEnvironment; @@ -87,7 +86,7 @@ public class PuzzleApplication extends Application { debugSpeed = true; } } else { - Game.setKey(e); + KeyboardInput.getKey().keyInput(e); } } @@ -98,8 +97,7 @@ public class PuzzleApplication extends Application { { debugSpeed = false; } else { - e.setKeyCode(KeyEvent.VK_UNDEFINED); - Game.setKey(e); + KeyboardInput.getKey().letGo(); } } }); @@ -120,10 +118,7 @@ public class PuzzleApplication extends Application { { if (!Display.isTransitionRunning()) { - if (Game.getKey() != null) - { - Game.getGameState().processInput(); - } + KeyboardInput.processInput(); Game.getGameState().doGameCycle(); } diff --git a/src/com/fourisland/fourpuzzle/gamestate/GameOverGameState.java b/src/com/fourisland/fourpuzzle/gamestate/GameOverGameState.java index ab1b9bb..d9b9ea1 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/GameOverGameState.java +++ b/src/com/fourisland/fourpuzzle/gamestate/GameOverGameState.java @@ -9,11 +9,10 @@ import com.fourisland.fourpuzzle.Audio; import com.fourisland.fourpuzzle.database.Database; import com.fourisland.fourpuzzle.Display; import com.fourisland.fourpuzzle.Game; +import com.fourisland.fourpuzzle.KeyInput; import com.fourisland.fourpuzzle.SaveFile; import com.fourisland.fourpuzzle.database.Music; import com.fourisland.fourpuzzle.database.Transitions; -import com.fourisland.fourpuzzle.transition.SquareTransition; -import com.fourisland.fourpuzzle.transition.TransitionDirection; import com.fourisland.fourpuzzle.util.ObjectLoader; import java.awt.Graphics2D; import java.awt.event.KeyEvent; @@ -34,9 +33,9 @@ public class GameOverGameState implements GameState { Audio.stopMusic(); } - public void processInput() + public void processInput(KeyInput key) { - if ((Game.getKey().getKeyCode() == KeyEvent.VK_ENTER) || (Game.getKey().getKeyCode() == KeyEvent.VK_SPACE)) + if ((key.getKey() == KeyEvent.VK_ENTER) || (key.getKey() == KeyEvent.VK_SPACE)) { Game.setSaveFile(new SaveFile()); diff --git a/src/com/fourisland/fourpuzzle/gamestate/GameState.java b/src/com/fourisland/fourpuzzle/gamestate/GameState.java index e7bd783..ff5b656 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/GameState.java +++ b/src/com/fourisland/fourpuzzle/gamestate/GameState.java @@ -5,18 +5,18 @@ package com.fourisland.fourpuzzle.gamestate; +import com.fourisland.fourpuzzle.util.Inputable; import com.fourisland.fourpuzzle.util.Renderable; /** * * @author hatkirby */ -public interface GameState extends Renderable { +public interface GameState extends Renderable, Inputable { public void initalize(); public void deinitalize(); - public void processInput(); public void doGameCycle(); } \ No newline at end of file diff --git a/src/com/fourisland/fourpuzzle/gamestate/TitleScreenGameState.java b/src/com/fourisland/fourpuzzle/gamestate/TitleScreenGameState.java index fe8b1ed..432d245 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/TitleScreenGameState.java +++ b/src/com/fourisland/fourpuzzle/gamestate/TitleScreenGameState.java @@ -7,6 +7,7 @@ package com.fourisland.fourpuzzle.gamestate; import com.fourisland.fourpuzzle.database.Database; import com.fourisland.fourpuzzle.*; +import com.fourisland.fourpuzzle.KeyInput; import com.fourisland.fourpuzzle.database.Music; import com.fourisland.fourpuzzle.database.Sound; import com.fourisland.fourpuzzle.database.Transitions; @@ -43,11 +44,11 @@ public class TitleScreenGameState implements GameState { } PauseTimer pt = new PauseTimer(0); - public void processInput() + public void processInput(KeyInput key) { if (pt.isElapsed()) { - if (Game.getKey().getKeyCode() == KeyEvent.VK_ENTER) + if (key.getKey() == KeyEvent.VK_ENTER) { Audio.playSound(Database.getSound(Sound.Selection)); @@ -89,12 +90,12 @@ public class TitleScreenGameState implements GameState { } }).start(); } - } else if (Game.getKey().getKeyCode() == KeyEvent.VK_UP) + } else if (key.getKey() == KeyEvent.VK_UP) { choices.moveUp(); pt.setTimer(1); - } else if (Game.getKey().getKeyCode() == KeyEvent.VK_DOWN) + } else if (key.getKey() == KeyEvent.VK_DOWN) { choices.moveDown(); diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java index a20062d..1213b0c 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java @@ -11,6 +11,7 @@ import com.fourisland.fourpuzzle.Direction; import com.fourisland.fourpuzzle.Display; import com.fourisland.fourpuzzle.gamestate.mapview.event.HeroEvent; import com.fourisland.fourpuzzle.Game; +import com.fourisland.fourpuzzle.KeyInput; import com.fourisland.fourpuzzle.Layer; import com.fourisland.fourpuzzle.PuzzleApplication; import com.fourisland.fourpuzzle.database.Database; @@ -34,7 +35,6 @@ import java.awt.image.BufferedImage; public class MapViewGameState implements GameState { public boolean debugWalkthrough = false; - boolean processInput = true; Map currentMap; Viewpoint currentViewpoint = null; @@ -61,90 +61,85 @@ public class MapViewGameState implements GameState { // Do nothing, yet } - public void processInput() + public void processInput(KeyInput key) { - if (processInput) - { - HeroEvent hero = Game.getSaveFile().getHero(); + HeroEvent hero = Game.getSaveFile().getHero(); - if (Game.getKey().isControlDown() && !debugWalkthrough) + if (key.isCtrlDown() && !debugWalkthrough) + { + if (PuzzleApplication.INSTANCE.getContext().getResourceMap().getBoolean("debugMode")) { - if (PuzzleApplication.INSTANCE.getContext().getResourceMap().getBoolean("debugMode")) - { - debugWalkthrough = true; - } - } else { - debugWalkthrough = false; + debugWalkthrough = true; } + } else { + debugWalkthrough = false; + } - if (!hero.isMoving() && !MoveEventThread.isHeroActive() && !EventHandler.isRunningEvent()) - { - Direction toMove = null; - Boolean letsMove = false; + if (!hero.isMoving() && !MoveEventThread.isHeroActive() && !EventHandler.isRunningEvent()) + { + Direction toMove = null; + Boolean letsMove = false; - switch (Game.getKey().getKeyCode()) - { - case KeyEvent.VK_UP: - toMove = Direction.North; - letsMove = true; - break; - case KeyEvent.VK_RIGHT: - toMove = Direction.East; - letsMove = true; - break; - case KeyEvent.VK_DOWN: - toMove = Direction.South; - letsMove = true; - break; - case KeyEvent.VK_LEFT: - toMove = Direction.West; - letsMove = true; - break; - } + switch (key.getKey()) + { + case KeyEvent.VK_UP: + toMove = Direction.North; + letsMove = true; + break; + case KeyEvent.VK_RIGHT: + toMove = Direction.East; + letsMove = true; + break; + case KeyEvent.VK_DOWN: + toMove = Direction.South; + letsMove = true; + break; + case KeyEvent.VK_LEFT: + toMove = Direction.West; + letsMove = true; + break; + } - if (letsMove) + if (letsMove) + { + if (!hero.startMoving(toMove)) { - if (!hero.startMoving(toMove)) + for (LayerEvent ev : currentMap.getEvents()) { - for (LayerEvent ev : currentMap.getEvents()) + if (ev.getCalltime() == EventCallTime.OnHeroTouch) { - if (ev.getCalltime() == EventCallTime.OnHeroTouch) + if (ev.getLayer() == Layer.Middle) { - if (ev.getLayer() == Layer.Middle) + if (Functions.isFacing(hero, ev)) { - if (Functions.isFacing(hero, ev)) - { - ev.getCallback().activate(ev.getCalltime()); - } + ev.getCallback().activate(ev.getCalltime()); } } } } } + } - if ((Game.getKey().getKeyCode() == KeyEvent.VK_ENTER) || (Game.getKey().getKeyCode() == KeyEvent.VK_SPACE)) + if ((key.getKey() == KeyEvent.VK_ENTER) || (key.getKey() == KeyEvent.VK_SPACE)) + { + for (LayerEvent ev : currentMap.getEvents()) { - for (LayerEvent ev : currentMap.getEvents()) + if (ev.getCalltime() == EventCallTime.PushKey) { - if (ev.getCalltime() == EventCallTime.PushKey) + if (ev.getLayer() == Layer.Middle) { - if (ev.getLayer() == Layer.Middle) + if (Functions.isFacing(hero, ev)) { - if (Functions.isFacing(hero, ev)) - { - ev.setDirection(hero.getDirection().opposite()); - ev.getCallback().activate(ev.getCalltime()); - } - } else { - if (ev.getLocation().equals(hero.getLocation())) - { - ev.getCallback().activate(ev.getCalltime()); - } + ev.setDirection(hero.getDirection().opposite()); + ev.getCallback().activate(ev.getCalltime()); + } + } else { + if (ev.getLocation().equals(hero.getLocation())) + { + ev.getCallback().activate(ev.getCalltime()); } } } - - Game.getKey().setKeyCode(KeyEvent.VK_UNDEFINED); } } } diff --git a/src/com/fourisland/fourpuzzle/util/Inputable.java b/src/com/fourisland/fourpuzzle/util/Inputable.java new file mode 100644 index 0000000..9b108b9 --- /dev/null +++ b/src/com/fourisland/fourpuzzle/util/Inputable.java @@ -0,0 +1,17 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.fourisland.fourpuzzle.util; + +import com.fourisland.fourpuzzle.KeyInput; + +/** + * + * @author hatkirby + */ +public interface Inputable { + + public void processInput(KeyInput key); +} diff --git a/src/com/fourisland/fourpuzzle/window/MessageWindow.java b/src/com/fourisland/fourpuzzle/window/MessageWindow.java index fb90f04..9ddd379 100644 --- a/src/com/fourisland/fourpuzzle/window/MessageWindow.java +++ b/src/com/fourisland/fourpuzzle/window/MessageWindow.java @@ -7,14 +7,15 @@ package com.fourisland.fourpuzzle.window; import com.fourisland.fourpuzzle.Display; import com.fourisland.fourpuzzle.Game; -import com.fourisland.fourpuzzle.PuzzleApplication; +import com.fourisland.fourpuzzle.KeyboardInput; +import com.fourisland.fourpuzzle.KeyInput; import com.fourisland.fourpuzzle.gamestate.mapview.FaceSet; +import com.fourisland.fourpuzzle.util.Inputable; import com.fourisland.fourpuzzle.util.Interval; import com.fourisland.fourpuzzle.util.Renderable; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.TexturePaint; -import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; @@ -59,48 +60,46 @@ public class MessageWindow implements Renderable { private static void displayMessage(final MessageWindow mw) throws InterruptedException { final CountDownLatch cdl = new CountDownLatch(1); - - Display.registerRenderable(mw); - - KeyAdapter ka = new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_ENTER) || (e.getKeyCode() == KeyEvent.VK_SPACE)) + Inputable in = new Inputable() { + public void processInput(KeyInput key) + { + if ((key.getKey() == KeyEvent.VK_ENTER) || (key.getKey() == KeyEvent.VK_SPACE)) { if (mw.pushEnter()) { cdl.countDown(); } } - - Game.setKey(null); } }; - PuzzleApplication.gameFrame.addKeyListener(ka); - + Display.registerRenderable(mw); + KeyboardInput.registerInputable(in); + cdl.await(); - PuzzleApplication.gameFrame.removeKeyListener(ka); Display.unregisterRenderable(mw); + KeyboardInput.unregisterInputable(in); } public static void displayMessage(String message) throws InterruptedException { - displayMessage(new MessageWindow(message)); + MessageWindow temp = new MessageWindow(message); + temp.initalizeMessages(message); + displayMessage(temp); } public static void displayMessage(String message, String faceSet, int face) throws InterruptedException { - displayMessage(new MessageWindow(message, faceSet, face)); + MessageWindow temp = new MessageWindow(message, faceSet, face); + temp.initalizeMessages(message); + displayMessage(temp); } - private void initalizeMessages(String message, Graphics2D g) + private void initalizeMessages(String message) { messages = new ArrayList(); - Display.setFont(g); - int length = width - SPACER; if (hasFace) { @@ -111,7 +110,7 @@ public class MessageWindow implements Renderable { int len = 0; while (!temp.isEmpty()) { - while ((g.getFontMetrics().stringWidth(temp.substring(0, len)) < length) && (len < temp.length())) + while ((Display.getFontMetrics().stringWidth(temp.substring(0, len)) < length) && (len < temp.length())) { len++; } @@ -153,7 +152,7 @@ public class MessageWindow implements Renderable { { if (messages == null) { - initalizeMessages(message, g2); + initalizeMessages(message); } int y = MessageWindowLocation.Bottom.getY(); @@ -240,4 +239,5 @@ public class MessageWindow implements Renderable { return y; } } + } -- cgit 1.4.1