diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java index e67685f7..43483f68 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java @@ -1,5 +1,5 @@ // -// $Id: AtlantiBoard.java,v 1.3 2001/10/11 04:08:22 mdb Exp $ +// $Id: AtlantiBoard.java,v 1.4 2001/10/12 20:34:13 mdb Exp $ package com.threerings.venison; @@ -8,15 +8,18 @@ import java.awt.event.*; import javax.swing.*; import java.util.Iterator; +import com.samskivert.swing.Controller; import com.samskivert.swing.util.SwingUtil; import com.threerings.presents.dobj.DSet; +import com.threerings.venison.Log; + /** * Displays the tiles that make up the Venison board. */ public class VenisonBoard - extends JPanel implements TileCodes + extends JPanel implements TileCodes, VenisonCodes { /** The command posted when a tile is placed by the user on the * board. */ @@ -50,12 +53,32 @@ public class VenisonBoard */ public void setTiles (DSet tiles) { + // grab the new tiles _tiles = tiles; - // we need to recompute our desired dimensions and then have our - // parent adjust to our changed size - computeDimensions(); + // update our display + refreshTiles(); + } + + /** + * Instructs the board to refresh its display in case changes have + * occurred in the tiles set. + */ + public void refreshTiles () + { + Log.info("Refreshing tiles " + _tiles + "."); + + // recompute our desired dimensions and then have our parent + // adjust to our changed size + if (_tiles != null) { + computeDimensions(); + } + + // we may need to revalidate if our dimensions changed revalidate(); + + // we also have to repaint in case our dimensions didn't change + repaint(); } /** @@ -67,12 +90,18 @@ public class VenisonBoard * TILE_PLACED command will be dispatched to the * controller in scope. The coordinates and orientation of the tile * will have been set to the values specified by the user. + * + * @param tile the new tile to be placed or null if no tile is to + * currently be placed. */ public void setTileToBePlaced (VenisonTile tile) { _placingTile = tile; // update our internal state based on this new placing tile - updatePlacingInfo(true); + if (_placingTile != null) { + updatePlacingInfo(true); + } + // and repaint repaint(); } @@ -95,10 +124,12 @@ public class VenisonBoard g.translate(_tx, _ty); // iterate over our tiles, painting each of them - Iterator iter = _tiles.elements(); - while (iter.hasNext()) { - VenisonTile tile = (VenisonTile)iter.next(); - tile.paint(g, _origX, _origY); + if (_tiles != null) { + Iterator iter = _tiles.elements(); + while (iter.hasNext()) { + VenisonTile tile = (VenisonTile)iter.next(); + tile.paint(g, _origX, _origY); + } } // if we have a placing tile, draw that one as well @@ -135,9 +166,18 @@ public class VenisonBoard /** Called by our adapter when the mouse is clicked. */ protected void mouseClicked (MouseEvent evt) { - // if we have a placing tile, we want to dispatch a command - // letting the controller know that the user placed it - if (_placingTile != null) { + // if we have a placing tile and it's in a valid position, we want + // to dispatch an action letting the controller know that the user + // placed it + if (_placingTile != null && _validPlacement) { + // clear out the placing tile + _placingTile = null; + + // post the action + Controller.postAction(this, TILE_PLACED); + + // and repaint + repaint(); } } @@ -256,18 +296,20 @@ public class VenisonBoard int minX = 0, minY = 0; // figure out what our boundaries are - Iterator iter = _tiles.elements(); - while (iter.hasNext()) { - VenisonTile tile = (VenisonTile)iter.next(); - if (tile.x > maxX) { - maxX = tile.x; - } else if (tile.x < minX) { - minX = tile.x; - } - if (tile.y > maxY) { - maxY = tile.y; - } else if (tile.y < minY) { - minY = tile.y; + if (_tiles != null) { + Iterator iter = _tiles.elements(); + while (iter.hasNext()) { + VenisonTile tile = (VenisonTile)iter.next(); + if (tile.x > maxX) { + maxX = tile.x; + } else if (tile.x < minX) { + minX = tile.x; + } + if (tile.y > maxY) { + maxY = tile.y; + } else if (tile.y < minY) { + minY = tile.y; + } } } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java index 88ddf802..5352384a 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java @@ -3,8 +3,17 @@ package com.threerings.venison; +import java.awt.event.ActionEvent; + +import com.threerings.presents.dobj.AttributeChangedEvent; +import com.threerings.presents.dobj.DSet; +import com.threerings.presents.dobj.MessageEvent; + +import com.threerings.crowd.data.BodyObject; +import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.client.PlaceView; -import com.threerings.parlor.client.GameController; + +import com.threerings.parlor.turn.TurnGameController; import com.threerings.parlor.util.ParlorContext; import com.threerings.venison.Log; @@ -13,17 +22,87 @@ import com.threerings.venison.Log; * The main coordinator of user interface activities on the client-side of * the Venison game. */ -public class VenisonController extends GameController +public class VenisonController + extends TurnGameController implements VenisonCodes { + // documentation inherited + protected void didInit () + { + super.didInit(); + + // get a handle on our body object + _self = (BodyObject)_ctx.getClient().getClientObject(); + } + + // documentation inherited protected PlaceView createPlaceView () { - return new VenisonPanel(_ctx); + _panel = new VenisonPanel(_ctx, this); + return _panel; } - protected void gameDidStart () + // documentation inherited + public void willEnterPlace (PlaceObject plobj) { - super.gameDidStart(); + super.willEnterPlace(plobj); - Log.info("Venison game did start."); + // get a casted reference to our game object + _venobj = (VenisonObject)plobj; } + + // documentation inherited + protected void turnDidChange (String turnHolder) + { + super.turnDidChange(turnHolder); + + // if it's our turn, set the tile to be placed. otherwise clear it + // out + if (turnHolder.equals(_self.username)) { + Log.info("Setting tile to be placed: " + _venobj.currentTile); + _panel.board.setTileToBePlaced(_venobj.currentTile); + } + + // and refresh the tiles + _panel.board.refreshTiles(); + } + + // documentation inherited + public void attributeChanged (AttributeChangedEvent event) + { + super.attributeChanged(event); + + // handle the setting of the board state + if (event.getName().equals(VenisonObject.TILES)) { + _panel.board.setTiles(_venobj.tiles); + } + } + + // documentation inherited + public boolean handleAction (ActionEvent action) + { + if (action.getActionCommand().equals(TILE_PLACED)) { + // the user placed the tile into a valid location. the board + // will have updated the position and orientation information + // in the tile object accordingly, so we simply submit our + // move to the server + Object[] args = new Object[] { _venobj.currentTile }; + MessageEvent mevt = new MessageEvent( + _venobj.getOid(), PLACE_TILE_REQUEST, args); + _ctx.getDObjectManager().postEvent(mevt); + + } else { + return super.handleAction(action); + } + + return true; + } + + /** A reference to our game panel. */ + protected VenisonPanel _panel; + + /** A reference to our game panel. */ + protected VenisonObject _venobj; + + /** A reference to our body object. */ + protected BodyObject _self; } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java index 10cf0006..5e9530fb 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java @@ -6,6 +6,9 @@ package com.threerings.venison; import java.awt.BorderLayout; import javax.swing.*; +import com.samskivert.swing.Controller; +import com.samskivert.swing.ControllerProvider; + import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.client.PlaceView; @@ -15,14 +18,22 @@ import com.threerings.parlor.util.ParlorContext; * The top-level user interface component for the Venison game display. */ public class VenisonPanel - extends JPanel implements PlaceView + extends JPanel implements PlaceView, ControllerProvider { + /** A reference to the board that is accessible to the controller. */ + public VenisonBoard board; + /** * Constructs a new Venison game display. */ - public VenisonPanel (ParlorContext ctx) + public VenisonPanel (ParlorContext ctx, VenisonController controller) { - add(new JLabel("Venison panel"), BorderLayout.CENTER); + // add the board + board = new VenisonBoard(); + add(board, BorderLayout.CENTER); + + // we'll need this later to provide it + _controller = controller; } // documentation inherited @@ -36,4 +47,14 @@ public class VenisonPanel { Log.info("Panel left place."); } + + // documentation inherited + public Controller getController () + { + return _controller; + } + + /** A reference to our controller that we need to implement the {@link + * ControllerProvider} interface. */ + protected VenisonController _controller; } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java new file mode 100644 index 00000000..8e03a268 --- /dev/null +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java @@ -0,0 +1,22 @@ +// +// $Id: AtlantiCodes.java,v 1.1 2001/10/12 20:34:13 mdb Exp $ + +package com.threerings.venison; + +/** + * Constants used by the Venison game code. + */ +public interface VenisonCodes +{ + /** The name of the command posted by the {@link VenisonBoard} when + * the user places a tile into a valid position. */ + public static final String TILE_PLACED = "tile_placed"; + + /** The message submitted by the client to the server when they have + * chosen where they wish to place their tile. */ + public static final String PLACE_TILE_REQUEST = "place_tile"; + + /** The message submitted by the client to the server when they have + * chosen where they wish to place their piecen. */ + public static final String PLACE_PIECEN_REQUEST = "place_piecen"; +} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java index 2781e285..3df2dfcd 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java @@ -1,9 +1,9 @@ // -// $Id: AtlantiConfig.java,v 1.1 2001/10/09 20:27:35 mdb Exp $ +// $Id: AtlantiConfig.java,v 1.2 2001/10/12 20:34:13 mdb Exp $ package com.threerings.venison; -import com.threerings.parlor.data.GameConfig; +import com.threerings.parlor.game.GameConfig; public class VenisonConfig extends GameConfig { diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java index fc0cb944..a051cb36 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java @@ -1,24 +1,30 @@ // -// $Id: AtlantiObject.java,v 1.3 2001/10/11 04:08:22 mdb Exp $ +// $Id: AtlantiObject.java,v 1.4 2001/10/12 20:34:13 mdb Exp $ package com.threerings.venison; import com.threerings.presents.dobj.DSet; - -import com.threerings.parlor.data.GameObject; +import com.threerings.parlor.turn.TurnGameObject; /** * The distributed object used to maintain state for the Venison game. */ -public class VenisonObject extends GameObject +public class VenisonObject extends TurnGameObject { /** The field name of the tiles field. */ public static final String TILES = "tiles"; + /** The field name of the currentTile field. */ + public static final String CURRENT_TILE = "currentTile"; + /** A set containing all of the tiles that are in play in this * game. */ public DSet tiles = new DSet(VenisonTile.class); + /** The tile being placed by the current turn holder. This value is + * only valid while it is someone's turn. */ + public VenisonTile currentTile = new VenisonTile(); + /** * Requests that the tiles field be set to the specified * value. @@ -55,10 +61,20 @@ public class VenisonObject extends GameObject requestElementUpdate(TILES, elem); } + /** + * Requests that the currentTile field be set to the + * specified value. + */ + public void setCurrentTile (VenisonTile value) + { + requestAttributeChange(CURRENT_TILE, value); + } + // documentation inherited protected void toString (StringBuffer buf) { super.toString(buf); buf.append(", tiles=").append(tiles); + buf.append(", currentTile=").append(currentTile); } } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java index e3cb9681..0c372dc6 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java @@ -1,5 +1,5 @@ // -// $Id: AtlantiTile.java,v 1.3 2001/10/11 04:08:22 mdb Exp $ +// $Id: AtlantiTile.java,v 1.4 2001/10/12 20:34:13 mdb Exp $ package com.threerings.venison; @@ -154,4 +154,11 @@ public class VenisonTile x = in.readInt(); y = in.readInt(); } + + public String toString () + { + return "[type=" + type + ", shield=" + hasShield + + ", orient=" + ORIENT_NAMES[orientation] + + ", pos=" + x + "/" + y + "]"; + } } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java b/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java index a1dfeae1..d031ba87 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java @@ -1,16 +1,21 @@ // -// $Id: AtlantiManager.java,v 1.4 2001/10/11 04:08:22 mdb Exp $ +// $Id: AtlantiManager.java,v 1.5 2001/10/12 20:34:13 mdb Exp $ package com.threerings.venison; +import java.util.Collections; +import java.util.List; + import com.threerings.presents.dobj.DSet; -import com.threerings.parlor.server.GameManager; +import com.threerings.presents.dobj.MessageEvent; + +import com.threerings.parlor.turn.TurnGameManager; /** * The main coordinator of the Venison game on the server side. */ public class VenisonManager - extends GameManager + extends TurnGameManager implements VenisonCodes { // documentation inherited protected Class getPlaceObjectClass () @@ -18,6 +23,17 @@ public class VenisonManager return VenisonObject.class; } + // documentation inherited + protected void didInit () + { + super.didInit(); + + // register our message handlers + registerMessageHandler(PLACE_TILE_REQUEST, new PlaceTileHandler()); + registerMessageHandler( + PLACE_PIECEN_REQUEST, new PlacePiecenHandler()); + } + // documentation inherited protected void didStartup () { @@ -35,10 +51,48 @@ public class VenisonManager { super.gameWillStart(); + // generate a shuffled tile list + _tiles = TileUtil.getStandardTileSet(); + Collections.shuffle(_tiles); + // clear out the tile set _venobj.setTiles(new DSet(VenisonTile.class)); _venobj.addToTiles(TileUtil.STARTING_TILE); } + protected void turnWillStart () + { + // let the players know what the next tile is that should be + // played + VenisonTile tile = (VenisonTile)_tiles.remove(0); + _venobj.setCurrentTile(tile); + } + + /** Handles place tile requests. */ + protected class PlaceTileHandler implements MessageHandler + { + public void handleEvent (MessageEvent event) + { + VenisonTile tile = (VenisonTile)event.getArgs()[0]; + // don't do no checking at present + _venobj.addToTiles(tile); + // and since they placed their tile, we end the turn + endTurn(); + } + } + + /** Handles place piecen requests. */ + protected class PlacePiecenHandler implements MessageHandler + { + public void handleEvent (MessageEvent event) + { + } + } + + /** A casted reference to our Venison game object. */ protected VenisonObject _venobj; + + /** The (shuffled) list of tiles remaining to be played in this + * game. */ + protected List _tiles; }