- Revision
- 621
- Author
- sirenian
- Date
- 2006-12-08 06:46:09 -0600 (Fri, 08 Dec 2006)
Log Message
[EK] Some more Hellbound stuff - Hellbound is nearly playable!
Modified Paths
- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java
- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/gui/HellboundFrameBehaviour.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/Hellbound.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/Segments.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/game/GameState.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/CollisionDetector.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/PseudoRandomGlyphFactory.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/ComponentNames.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/HellboundFrame.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/PitPanel.java
- trunk/examples/hellbound/src/stories/com/sirenian/hellbound/scenarios/ThePlayerRotatesTheGlyphLeft.java
- trunk/extensions/swing/src/java/org/jbehave/threaded/swing/Idler.java
Diff
Modified: trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java (620 => 621)
--- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java 2006-12-08 12:46:09 UTC (rev 621) @@ -149,6 +149,24 @@ verifyMocks(); } + public void shouldEndGameWhenTheNewGlyphOverlapsTheJunk() { + StubHeartbeat heartbeat = new StubHeartbeat(); + Game game = new Game(new PseudoRandomGlyphFactory(42, 7, 2), heartbeat, 7, 2); // pit is only 2 deep! + + Mock gameListener = mock(GameListener.class); + game.requestStartGame(); + + gameListener.expects("reportGameStateChanged").with(GameState.RUNNING); + gameListener.expects("reportGameStateChanged").with(GameState.OVER); + game.addGameListener((GameListener) gameListener); + + + heartbeat.beat(); // first glyph falls; cannot add second glyph as it overlaps + + verifyMocks(); + + } + private Segments droppedToFloor(Segments segments, int floor) { Segments result = segments; while(result.lowest() < floor) {
Modified: trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/gui/HellboundFrameBehaviour.java (620 => 621)
--- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/gui/HellboundFrameBehaviour.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/gui/HellboundFrameBehaviour.java 2006-12-08 12:46:09 UTC (rev 621) @@ -2,11 +2,13 @@ import java.awt.event.KeyEvent; +import javax.swing.JLabel; import javax.swing.JPanel; import org.jbehave.core.minimock.UsingMiniMock; import org.jbehave.core.mock.Mock; import org.jbehave.threaded.swing.DefaultWindowWrapper; +import org.jbehave.threaded.swing.Idler; import org.jbehave.threaded.time.TimeoutException; import com.sirenian.hellbound.domain.game.GameRequestListener; @@ -24,7 +26,9 @@ public void setUp() { windowWrapper = new DefaultWindowWrapper(ComponentNames.HELLBOUND_FRAME); frontPanel = new JPanel(); + frontPanel.setName("front.panel"); gamePanel = new JPanel(); + gamePanel.setName("game.panel"); gameRequestListener = mock(GameRequestListener.class); frame = new HellboundFrame(frontPanel, gamePanel); frame.setGameRequestListener((GameRequestListener) gameRequestListener); @@ -50,6 +54,16 @@ ensureThat(gamePanel.isShowing()); } + public void shouldHaveLabelDisplayingGameOverMessageWhenGameOver() throws Exception { + frame.reportGameStateChanged(GameState.RUNNING); + new Idler().waitForIdle(); + JLabel label = (JLabel) windowWrapper.findComponent(ComponentNames.GAME_MESSAGE); + ensureThat(label.getText(), eq("")); + frame.reportGameStateChanged(GameState.OVER); + new Idler().waitForIdle(); + ensureThat(label.getText(), eq("Game over, man! Game over!")); + } + public void shouldRequestThatTheShapeIsDroppedWhenTheSpaceKeyIsPressed() throws Exception { ensureThatKeycodeProducesRequest(' ', GlyphMovement.DROP); } @@ -72,7 +86,6 @@ public void shouldRequestThatTheShapeIsRotatedRightWhenTheXKeyIsPressed() throws Exception { ensureThatKeycodeProducesRequest('x', GlyphMovement.ROTATE_RIGHT); - } private void ensureThatKeycodeProducesRequest(int keycode, GlyphMovement movement) throws TimeoutException {
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/Hellbound.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/Hellbound.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/Hellbound.java 2006-12-08 12:46:09 UTC (rev 621) @@ -55,7 +55,7 @@ Game game = createEngineForGame(heartbeat, factory); connectQueues(engineQueue, guiQueue, pitPanel, frame, game); - bindQueuesToFrame(engineQueue, guiQueue, frame); + bindThreadsToFrame(engineQueue, guiQueue, heartbeat, frame); startHellbound(frame); } @@ -90,11 +90,13 @@ } - private void bindQueuesToFrame(final EngineQueue engineQueue, final GuiQueue guiQueue, HellboundFrame frame) { + private void bindThreadsToFrame(final EngineQueue engineQueue, final GuiQueue guiQueue, final Heartbeat heartbeat, HellboundFrame frame) { WindowAdapter queueLife = new WindowAdapter() { - public void windowClosed(WindowEvent e) { + + public void windowClosing(WindowEvent e) { engineQueue.stop(); guiQueue.stop(); + heartbeat.stop(); } };
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/Segments.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/Segments.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/Segments.java 2006-12-08 12:46:09 UTC (rev 621) @@ -1,5 +1,7 @@ package com.sirenian.hellbound.domain; +import com.sirenian.hellbound.util.Logger; + /** * This class should be immutable. */ @@ -110,6 +112,7 @@ public boolean overlaps(Segments segments) { for (int i = 0; i < segments.size(); i++) { if (contains(segments.get(i))) { + Logger.debug(this, "Segments overlap at " + segments.get(i)); return true; } }
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/game/GameState.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/game/GameState.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/game/GameState.java 2006-12-08 12:46:09 UTC (rev 621) @@ -15,6 +15,7 @@ public static final GameState READY = new GameState("READY"); public static final GameState RUNNING = new GameState("RUNNING"); + public static final GameState OVER = new GameState("OVER"); } \ No newline at end of file
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java 2006-12-08 12:46:09 UTC (rev 621) @@ -4,6 +4,7 @@ import com.sirenian.hellbound.domain.Segments; import com.sirenian.hellbound.engine.CollisionDetector; import com.sirenian.hellbound.util.ListenerSet; +import com.sirenian.hellbound.util.Logger; public class LivingGlyph extends Glyph { @@ -59,6 +60,7 @@ private boolean attemptMoveTo(Segments newSegments, int newRotations, Segment newRoot) { if (detector.collides(newSegments)) { + Logger.debug(this, "Detector " + detector + " collided; cannot move."); return false; } else { moveTo(newSegments);
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/CollisionDetector.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/CollisionDetector.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/CollisionDetector.java 2006-12-08 12:46:09 UTC (rev 621) @@ -8,6 +8,7 @@ public boolean collides(Segments segments) { return true; // not false, or could get into real trouble. } + public String toString() { return CollisionDetector.class.getName() + ".NULL"; } }; boolean collides(Segments segments);
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java 2006-12-08 12:46:09 UTC (rev 621) @@ -76,6 +76,11 @@ private void resetGlyph() { glyph = factory.nextGlyph(collisionDetector, glyphListeners); + if (glyph.getSegments().overlaps(junk.getSegments())) { + setState(GameState.OVER); + glyph = glyph.NULL; + junk = junk.NULL; + } } private void setState(GameState newState) { @@ -98,7 +103,7 @@ public void requestGlyphMovement(GlyphMovement movement) { if (state == GameState.RUNNING) { - Logger.debug(this, "Glyph movement " + movement + "requested"); + Logger.debug(this, "Glyph movement " + movement + " requested"); boolean result = movement.performOn(glyph); if (result == false && movement == GlyphMovement.DOWN) {
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/PseudoRandomGlyphFactory.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/PseudoRandomGlyphFactory.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/PseudoRandomGlyphFactory.java 2006-12-08 12:46:09 UTC (rev 621) @@ -6,6 +6,7 @@ import com.sirenian.hellbound.domain.glyph.Junk; import com.sirenian.hellbound.domain.glyph.LivingGlyph; import com.sirenian.hellbound.util.ListenerSet; +import com.sirenian.hellbound.util.Logger; public class PseudoRandomGlyphFactory implements GlyphFactory { @@ -25,6 +26,7 @@ public LivingGlyph nextGlyph(CollisionDetector detector, ListenerSet glyphListeners) { GlyphType glyphType = GlyphType.ALL_LIVING[random.nextInt(GlyphType.ALL_LIVING.length)]; + Logger.debug(this, "Creating next glyph, glyph type is " + glyphType); LivingGlyph glyph = new LivingGlyph(glyphType, detector, CenterCalculator.forWidth(width)); glyph.addListeners(glyphListeners); return glyph;
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/ComponentNames.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/ComponentNames.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/ComponentNames.java 2006-12-08 12:46:09 UTC (rev 621) @@ -5,4 +5,5 @@ public static final String HELLBOUND_FRAME = "HellboundFrame"; public static final String START_GAME_BUTTON = "startGame.button"; public static final String DROP_GLYPH_BUTTON = "dropGlyph.button"; + public static final String GAME_MESSAGE = "gameMessage.label"; }
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/HellboundFrame.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/HellboundFrame.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/HellboundFrame.java 2006-12-08 12:46:09 UTC (rev 621) @@ -1,9 +1,12 @@ package com.sirenian.hellbound.gui; +import java.awt.BorderLayout; import java.awt.CardLayout; +import java.awt.Dimension; import java.awt.event.KeyEvent; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.KeyStroke; @@ -16,19 +19,22 @@ public class HellboundFrame extends JFrame implements GameListener { private CardLayout cardLayout = new CardLayout(); - private JPanel contentPanel = new JPanel(); + private JPanel contentPanel = new JPanel(cardLayout); + private JLabel messageLabel = new JLabel(); private ActionFactory actionFactory = new ActionFactory(); - public HellboundFrame(JPanel readyPanel, JPanel runningPanel) { + public HellboundFrame(JPanel readyPanel, JPanel pitPanel) { setName(ComponentNames.HELLBOUND_FRAME); + messageLabel.setName(ComponentNames.GAME_MESSAGE); + messageLabel.setPreferredSize(new Dimension((int)pitPanel.getPreferredSize().getWidth(), 100)); + + contentPanel.setName("Hellbound frame content panel"); setContentPane(contentPanel); - contentPanel.setLayout(cardLayout); - contentPanel.add(readyPanel, GameState.READY.toString()); - contentPanel.add(runningPanel, GameState.RUNNING.toString()); + contentPanel.add(createRunningPanel(pitPanel), GameState.RUNNING.toString()); contentPanel.getInputMap().put(KeyStroke.getKeyStroke(' '), "drop"); contentPanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right"); @@ -43,6 +49,15 @@ this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } + private JPanel createRunningPanel(JPanel pitPanel) { + JPanel runningPanel = new JPanel(); + runningPanel.setName("running.panel"); + runningPanel.setLayout(new BorderLayout()); + runningPanel.add(pitPanel, BorderLayout.CENTER); + runningPanel.add(messageLabel, BorderLayout.NORTH); + return runningPanel; + } + public void setGameRequestListener(final GameRequestListener gameRequestListener) { contentPanel.getActionMap().clear(); contentPanel.getActionMap().put("drop", actionFactory.createAction(gameRequestListener, GlyphMovement.DROP)); @@ -55,6 +70,11 @@ public void reportGameStateChanged(GameState state) { Logger.debug(this, "gameStateChanged to " + state); - cardLayout.show(this.getContentPane(), state.toString()); + if (state == GameState.OVER) { + messageLabel.setText("Game over, man! Game over!"); + } else { + messageLabel.setText(""); + cardLayout.show(this.getContentPane(), state.toString()); + } } }
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/PitPanel.java (620 => 621)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/PitPanel.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/gui/PitPanel.java 2006-12-08 12:46:09 UTC (rev 621) @@ -32,7 +32,11 @@ this.pitHeight = height; this.colorMap = colorMap; - this.setPreferredSize(new Dimension(scale * pitWidth, scale * pitHeight)); + Dimension dimension = new Dimension(scale * pitWidth, scale * pitHeight); + + this.setPreferredSize(dimension); + this.setMinimumSize(dimension); + this.setMaximumSize(dimension); } public void reportGlyphMovement(GlyphType type, Segments fromSquares, Segments toSquares) { @@ -63,7 +67,7 @@ if (type == null) { type = GlyphType.PIT; } Color color = colorMap.getColorFor(type); g.setColor(color); - g.fillRect(getBounds().x + (scale * i), getBounds().y + (scale * j), scale, scale); + g.fillRect((scale * i), (scale * j), scale, scale); } } }
Modified: trunk/examples/hellbound/src/stories/com/sirenian/hellbound/scenarios/ThePlayerRotatesTheGlyphLeft.java (620 => 621)
--- trunk/examples/hellbound/src/stories/com/sirenian/hellbound/scenarios/ThePlayerRotatesTheGlyphLeft.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/examples/hellbound/src/stories/com/sirenian/hellbound/scenarios/ThePlayerRotatesTheGlyphLeft.java 2006-12-08 12:46:09 UTC (rev 621) @@ -12,6 +12,7 @@ public void specify() { given(new TheFirstGlyphIsDisplayedOnTheBoard()); + when(new ThePlayerPressesLeftRotate()); then(new TheGlyphShouldTurnToOneQuarter());
Modified: trunk/extensions/swing/src/java/org/jbehave/threaded/swing/Idler.java (620 => 621)
--- trunk/extensions/swing/src/java/org/jbehave/threaded/swing/Idler.java 2006-12-08 11:43:03 UTC (rev 620) +++ trunk/extensions/swing/src/java/org/jbehave/threaded/swing/Idler.java 2006-12-08 12:46:09 UTC (rev 621) @@ -8,13 +8,8 @@ public class Idler { private static final Runnable EMPTY_RUNNABLE = new Runnable() { public void run() {}}; - - private Toolkit toolkit; - private EventQueue sysQueue; public Idler() { - toolkit = Toolkit.getDefaultToolkit(); - sysQueue = toolkit.getSystemEventQueue(); } public void waitForIdle() {
To unsubscribe from this list please visit:
