diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java new file mode 100644 index 00000000..cf0b5c40 --- /dev/null +++ b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java @@ -0,0 +1,143 @@ +// +// $Id: AtlantiBoard.java,v 1.1 2001/10/10 03:35:02 mdb Exp $ + +package com.threerings.venison; + +import java.awt.*; +import javax.swing.*; +import java.util.Iterator; + +import com.samskivert.swing.util.SwingUtil; + +import com.threerings.cocktail.cher.dobj.DSet; + +/** + * Displays the tiles that make up the Venison board. + */ +public class VenisonBoard + extends JPanel implements VenisonTileCodes +{ + /** + * Sets the tiles that are displayed by this board. Causes the board + * to recompute its size based on the new tile layout. + * + * @param tiles the set of {@link VenisonTile} objects to be displayed + * by this board. + */ + public void setTiles (DSet tiles) + { + _tiles = tiles; + + // we need to recompute our desired dimensions and then have our + // parent adjust to our changed size + computeDimensions(); + revalidate(); + } + + // documentation inherited + public void paintComponent (Graphics g) + { + super.paintComponent(g); + + // center the tile display if we are bigger than we need to be + int tx = (getWidth() - TILE_WIDTH * _width)/2; + int ty = (getHeight() - TILE_HEIGHT * _height)/2; + 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); + } + + // undo our translations + g.translate(-tx, -ty); + } + + // documentation inherited + public Dimension getPreferredSize () + { + if (_tiles == null) { + return new Dimension(100, 100); + + } else { + return new Dimension(TILE_WIDTH * _width, TILE_HEIGHT * _height); + } + } + + /** + * Determines how big we want to be based on where the tiles have been + * laid out. + */ + protected void computeDimensions () + { + int maxX = 0, maxY = 0; + 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; + } + } + + // now we can compute our width and the origin offset + _origX = -minX; + _origY = -minY; + _width = maxX - minX + 1; + _height = maxY - minY + 1; + } + + /** Test code. */ + public static void main (String[] args) + { + JFrame frame = new JFrame("Board test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + VenisonBoard board = new VenisonBoard(); + + TestDSet set = new TestDSet(); + set.addTile(new VenisonTile(CITY_FOUR, false, NORTH, 0, 1)); + set.addTile(new VenisonTile(CITY_THREE, false, NORTH, 1, 1)); + set.addTile(new VenisonTile(CITY_THREE_ROAD, false, NORTH, 1, 2)); + set.addTile(new VenisonTile(CITY_THREE, false, NORTH, -1, 0)); + set.addTile(new VenisonTile(CITY_FOUR, false, NORTH, -2, 0)); + board.setTiles(set); + + frame.getContentPane().add(board, BorderLayout.CENTER); + frame.pack(); + SwingUtil.centerWindow(frame); + frame.show(); + } + + protected static class TestDSet extends DSet + { + public TestDSet () + { + super(VenisonTile.class); + } + + public void addTile (VenisonTile tile) + { + add(tile); + } + } + + /** A reference to our tile set. */ + protected DSet _tiles; + + /** The offset in tile coordinates of the origin. */ + protected int _origX, _origY; + + /** The width and height of the board in tile coordinates. */ + protected int _width, _height; +} 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 f2d3eaee..3a634c95 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java @@ -22,6 +22,8 @@ public class VenisonController extends GameController protected void gameDidStart () { + super.gameDidStart(); + Log.info("Venison game did start."); } } 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 5ab6bb70..19fcbc1b 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java @@ -1,8 +1,10 @@ // -// $Id: AtlantiObject.java,v 1.1 2001/10/09 20:27:35 mdb Exp $ +// $Id: AtlantiObject.java,v 1.2 2001/10/10 03:35:02 mdb Exp $ package com.threerings.venison; +import com.threerings.cocktail.cher.dobj.DSet; + import com.threerings.parlor.data.GameObject; /** @@ -10,4 +12,53 @@ import com.threerings.parlor.data.GameObject; */ public class VenisonObject extends GameObject { + /** The field name of the tiles field. */ + public static final String TILES = "tiles"; + + /** A set containing all of the tiles that are in play in this + * game. */ + public DSet tiles = new DSet(VenisonTile.class); + + /** + * Requests that the tiles field be set to the specified + * value. + */ + public void setTiles (DSet value) + { + requestAttributeChange(TILES, value); + } + + /** + * Requests that the specified element be added to the + * tiles set. + */ + public void addToTiles (DSet.Element elem) + { + requestElementAdd(TILES, elem); + } + + /** + * Requests that the element matching the supplied key be removed from + * the tiles set. + */ + public void removeFromTiles (Object key) + { + requestElementRemove(TILES, key); + } + + /** + * Requests that the specified element be updated in the + * tiles set. + */ + public void updateTiles (DSet.Element elem) + { + requestElementUpdate(TILES, elem); + } + + // documentation inherited + protected void toString (StringBuffer buf) + { + super.toString(buf); + buf.append(", tiles=").append(tiles); + } } diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java new file mode 100644 index 00000000..42e982c8 --- /dev/null +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java @@ -0,0 +1,110 @@ +// +// $Id: AtlantiTile.java,v 1.1 2001/10/10 03:35:02 mdb Exp $ + +package com.threerings.venison; + +import java.awt.Graphics; + +import java.io.IOException; +import java.io.DataInputStream; +import java.io.DataOutputStream; + +import com.threerings.cocktail.cher.dobj.DSet; + +/** + * Represents a single tile in play on the Venison game board. + */ +public class VenisonTile + implements DSet.Element, VenisonTileCodes +{ + /** The starting tile. */ + public static final VenisonTile STARTING_TILE = + new VenisonTile(CITY_ONE_ROAD_STRAIGHT, false, NORTH, 0, 0); + + /** The tile type. */ + public int type; + + /** Whether this tile has a shield on it. */ + public boolean hasShield; + + /** The tile's orientation. */ + public int orientation; + + /** The tile's x and y coordinates. */ + public int x, y; + + /** + * Constructs a tile with all of the supplied tile information. + */ + public VenisonTile (int type, boolean hasShield, int orientation, + int x, int y) + { + this.type = type; + this.hasShield = hasShield; + this.orientation = orientation; + this.x = x; + this.y = y; + } + + /** + * Constructs a blank tile, suitable for unserialization. + */ + public VenisonTile () + { + // nothing doing + } + + /** + * Paints this tile to the specified graphics context at its assigned + * location, accounting for the supplied x and y offsets of the + * origin. + * + * @param g the graphics context to use when painting the tile. + * @param xoff the offset (in tile units) of the origin in the x + * direction. + * @param yoff the offset (in tile units) of the origin in the y + * direction. + */ + public void paint (Graphics g, int xoff, int yoff) + { + // compute our screen coordinates + int sx = (x + xoff) * TILE_WIDTH; + int sy = (y + yoff) * TILE_HEIGHT; + + // draw a rectangle + g.drawRect(sx, sy, TILE_WIDTH, TILE_HEIGHT); + + // and draw our tile id in the middle for now (we'll eventually + // draw tile images) + g.drawString(type + "/" + x + "/" + y, sx + 20, sy + 20); + } + + // documentation inherited + public Object getKey () + { + // our key is our coordinates conflated into one integer + return new Integer((x + 128) * 256 + y + 128); + } + + // documentation inherited + public void writeTo (DataOutputStream out) + throws IOException + { + out.writeInt(type); + out.writeBoolean(hasShield); + out.writeInt(orientation); + out.writeInt(x); + out.writeInt(y); + } + + // documentation inherited + public void readFrom (DataInputStream in) + throws IOException + { + type = in.readInt(); + hasShield = in.readBoolean(); + orientation = in.readInt(); + x = in.readInt(); + y = in.readInt(); + } +} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java new file mode 100644 index 00000000..6bab75a1 --- /dev/null +++ b/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java @@ -0,0 +1,99 @@ +// +// $Id: TileCodes.java,v 1.1 2001/10/10 03:35:02 mdb Exp $ + +package com.threerings.venison; + +/** + * A repository for constants related to the tiles that are used in the + * game of Venison. + */ +public interface VenisonTileCodes +{ + /** A four-sided city tile. */ + public static final int CITY_FOUR = 1; + + /** A three-sided city tile. */ + public static final int CITY_THREE = 2; + + /** A three-sided city tile with a road. */ + public static final int CITY_THREE_ROAD = 3; + + /** A two-sided city tile with city openings adjacent to one + * another. */ + public static final int CITY_TWO = 4; + + /** A two-sided city tile with city openings adjacent to one another + * and a road connecting the other two sides. */ + public static final int CITY_TWO_ROAD = 5; + + /** A two-sided city tile with city openings on opposite sides of the + * tile. */ + public static final int CITY_TWO_ACROSS = 6; + + /** A two-sided city tile with two separate city arcs adjacent to one + * another and not connected to each other. */ + public static final int DISCONNECTED_CITY_TWO = 7; + + /** A two-sided city tile with two separate city arcs on opposite + * sides of the tile. */ + public static final int DISCONNECTED_CITY_TWO_ACROSS = 8; + + /** A one-sided city tile. */ + public static final int CITY_ONE = 9; + + /** A one-sided city tile with a city arc on top and a right facing + * curved road segment beneath it. */ + public static final int CITY_ONE_ROAD_RIGHT = 10; + + /** A one-sided city tile with a city arc on top and a left facing + * curved road segment beneath it. */ + public static final int CITY_ONE_ROAD_LEFT = 11; + + /** A one-sided city tile with a city arc on top and a road tee + * beneath it. */ + public static final int CITY_ONE_ROAD_TEE = 12; + + /** A one-sided city tile with a city arc on top and straight road + * segment beneath it. */ + public static final int CITY_ONE_ROAD_STRAIGHT = 13; + + /** A cloister tile. */ + public static final int CLOISTER = 14; + + /** A cloister tile with a road extending from the cloister. */ + public static final int CLOISTER_ROAD = 15; + + /** A four-way road intersection. */ + public static final int FOUR_WAY_ROAD = 16; + + /** A three-way road intersection. */ + public static final int THREE_WAY_ROAD = 17; + + /** A straight road segment. */ + public static final int STRAIGHT_ROAD = 18; + + /** A curved road segment. */ + public static final int CURVED_ROAD = 19; + + /** A tile orientation constant indicating the tile is in its default + * orientation. */ + public static final int NORTH = 0; + + /** A tile orientation constant indicating the tile is rotated 90 + * degrees clockwise from its default orientation. */ + public static final int EAST = 1; + + /** A tile orientation constant indicating the tile is rotated 180 + * degrees clockwise from its default orientation. */ + public static final int SOUTH = 2; + + /** A tile orientation constant indicating the tile is rotated 270 + * degrees clockwise from its default orientation. */ + public static final int WEST = 3; + + /** The tile image width in pixels. */ + public static int TILE_WIDTH = 90; + + /** The tile image height in pixels. */ + public static int TILE_HEIGHT = 90; +} 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 566ba8a8..bce70922 100644 --- a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java +++ b/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java @@ -1,18 +1,44 @@ // -// $Id: AtlantiManager.java,v 1.1 2001/10/09 20:27:35 mdb Exp $ +// $Id: AtlantiManager.java,v 1.2 2001/10/10 03:35:02 mdb Exp $ package com.threerings.venison; +import com.threerings.cocktail.cher.dobj.DSet; import com.threerings.parlor.server.GameManager; /** * The main coordinator of the Venison game on the server side. */ -public class VenisonManager extends GameManager +public class VenisonManager + extends GameManager { // documentation inherited protected Class getPlaceObjectClass () { return VenisonObject.class; } + + // documentation inherited + protected void didStartup () + { + super.didStartup(); + + // grab our own casted game object reference + _venobj = (VenisonObject)_gameobj; + } + + /** + * In preparation for starting the game, we clear out the tile set and + * put the starting tile into place. + */ + protected void gameWillStart () + { + super.gameWillStart(); + + // clear out the tile set + _venobj.setTiles(new DSet(VenisonTile.class)); + _venobj.addToTiles(VenisonTile.STARTING_TILE); + } + + protected VenisonObject _venobj; }