Title: [jbehave] [621] trunk/examples/hellbound/src/java/com/sirenian/hellbound: [EK] Some more Hellbound stuff - Hellbound is nearly playable!

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:

http://xircles.codehaus.org/manage_email

Reply via email to