Created tile feature geometry specifications and test code to draw the

geometry to make sure it is correct.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@356 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2001-10-15 19:55:15 +00:00
parent 25cf08c651
commit 7dc00b831e
2 changed files with 320 additions and 1 deletions
@@ -0,0 +1,132 @@
//
// $Id: TileGeometryTest.java,v 1.1 2001/10/15 19:55:15 mdb Exp $
package com.threerings.venison;
import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import com.samskivert.swing.util.SwingUtil;
import com.samskivert.util.IntTuple;
/**
* A simple class for testing the tile geometry specifications by drawing
* them.
*/
public class TileGeometryTest
extends JPanel implements TileCodes
{
public TileGeometryTest ()
{
ArrayList polys = new ArrayList();
ArrayList colors = new ArrayList();
// create polygons from the various tile features
for (int i = 1; i < TileUtil.TILE_FEATURES.length; i++) {
// convert tile index into x and y coordinates (in tile
// feature coords which will be converted to screen coords)
int x = 4 * (i % 5), y = 4 * (i / 5);
// the first feature is the background color
Object[] features = (Object[])TileUtil.TILE_FEATURES[i];
IntTuple base = (IntTuple)features[0];
// add a polygon containing the whole tile colored with the
// background color
colors.add(COLOR_MAP[base.left]);
Polygon poly = new Polygon();
poly.addPoint(((x + 0) * TILE_WIDTH) / 4,
((y + 0) * TILE_HEIGHT) / 4);
poly.addPoint(((x + 4) * TILE_WIDTH) / 4,
((y + 0) * TILE_HEIGHT) / 4);
poly.addPoint(((x + 4) * TILE_WIDTH) / 4,
((y + 4) * TILE_HEIGHT) / 4);
poly.addPoint(((x + 0) * TILE_WIDTH) / 4,
((y + 4) * TILE_HEIGHT) / 4);
polys.add(poly);
// the remainder are tuple/coordinate pairs
for (int f = 1; f < features.length; f += 2) {
IntTuple type = (IntTuple)features[f];
int[] coords = (int[])features[f+1];
// create a color for this polygon
colors.add(COLOR_MAP[type.left]);
// if this is a road segment, we need to create a special
// polygon
if (type.left == ROAD) {
poly = TileUtil.roadSegmentToPolygon(
coords[0], coords[1], coords[2], coords[3]);
// translate the polygon into our coordinate space
poly.translate((x * TILE_WIDTH)/4, (y * TILE_HEIGHT)/4);
} else {
// otherwise create the polygon directly from the coords
poly = new Polygon();
for (int c = 0; c < coords.length; c += 2) {
// translate and scale the coords accordingly
int fx = ((x + coords[c]) * TILE_WIDTH) / 4;
int fy = ((y + coords[c+1]) * TILE_HEIGHT) / 4;
poly.addPoint(fx, fy);
}
}
polys.add(poly);
}
}
// create our arrays
_polys = new Polygon[polys.size()];
polys.toArray(_polys);
_colors = new Color[colors.size()];
colors.toArray(_colors);
}
public void paintComponent (Graphics g)
{
super.paintComponent(g);
// paint our polygons
for (int i = 0; i < _polys.length; i++) {
g.setColor(_colors[i]);
g.fillPolygon(_polys[i]);
}
// outline the tiles
g.setColor(Color.black);
for (int i = 0; i < 20; i++) {
int x = i % 5, y = i / 5;
g.drawRect(TILE_WIDTH * x, TILE_HEIGHT * y,
TILE_WIDTH, TILE_HEIGHT);
}
}
public Dimension getPreferredSize ()
{
// we want to be five tiles wide by four tiles tall
return new Dimension(TILE_WIDTH * 5, TILE_HEIGHT * 4);
}
public static void main (String[] args)
{
JFrame frame = new JFrame("Tile geometry test");
// quit if we're closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TileGeometryTest panel = new TileGeometryTest();
frame.getContentPane().add(panel);
frame.pack();
SwingUtil.centerWindow(frame);
frame.show();
}
protected Polygon[] _polys;
protected Color[] _colors;
protected static Color[] COLOR_MAP = {
Color.red, // CITY
Color.green, // GRASS
Color.black // ROAD
};
}
@@ -1,12 +1,16 @@
//
// $Id: TileUtil.java,v 1.2 2001/10/11 04:00:49 mdb Exp $
// $Id: TileUtil.java,v 1.3 2001/10/15 19:55:15 mdb Exp $
package com.threerings.venison;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import com.samskivert.util.IntTuple;
/**
* Utility functions relating to the Venison tiles.
*/
@@ -176,6 +180,65 @@ public class TileUtil implements TileCodes
return TILE_EDGES[4*tileType + edge];
}
/**
* Massages a road segment (specified in tile feature coordinates)
* into a polygon (in screen coordinates) that can be used to render
* or hit test the road. The coordinates must obey the following
* constraints: (x1 < x2 and y1 == y2) or (x1 == x2 and y1 < y2) or
* (x1 < x2 and y1 > y2).
*
* @return a polygon representing the road segment (with origin at 0,
* 0).
*/
public static Polygon roadSegmentToPolygon (
int x1, int y1, int x2, int y2)
{
// first convert the coordinates into screen coordinates
x1 = (x1 * TILE_WIDTH) / 4;
y1 = (y1 * TILE_HEIGHT) / 4;
x2 = (x2 * TILE_WIDTH) / 4;
y2 = (y2 * TILE_HEIGHT) / 4;
Polygon poly = new Polygon();
int dx = 4, dy = 4;
// figure out what sort of line segment it is
if (x1 == x2) { // vertical
// make adjustments to ensure that we stay inside the tile
// bounds
if (y1 == 0) {
y1 += dy;
} else if (y2 == TILE_HEIGHT) {
y2 -= dy;
}
poly.addPoint(x1 - dx, y1 - dy);
poly.addPoint(x1 + dx, y1 - dy);
poly.addPoint(x2 + dx, y2 + dy);
poly.addPoint(x2 - dx, y2 + dy);
} else if (y1 == y2) { // horizontal
// make adjustments to ensure that we stay inside the tile
// bounds
if (x1 == 0) {
x1 += dx;
} else if (x2 == TILE_WIDTH) {
x2 -= dx;
}
poly.addPoint(x1 - dx, y1 - dy);
poly.addPoint(x1 - dx, y1 + dy);
poly.addPoint(x2 + dx, y2 + dy);
poly.addPoint(x2 + dx, y2 - dy);
} else { // diagonal
poly.addPoint(x1 - dx, y1);
poly.addPoint(x1 + dx, y1);
poly.addPoint(x2, y2 + dy);
poly.addPoint(x2, y2 - dy);
}
return poly;
}
/** Used to generate our standard tile set. */
protected static void addTiles (int count, List list, VenisonTile tile)
{
@@ -254,4 +317,128 @@ public class TileUtil implements TileCodes
ROAD, GRASS, ROAD, GRASS, // STRAIGHT_ROAD
GRASS, GRASS, ROAD, ROAD, // CURVED_ROAD
};
/** A table describing the geometry of the features (cities, roads,
* etc.) of each tile. */
protected static final Object[] TILE_FEATURES = new Object[] {
new Object[0], // null tile
new Object[] { new IntTuple(CITY, 0), }, // CITY_FOUR
new Object[] { new IntTuple(CITY, 0), // CITY_THREE
new IntTuple(GRASS, 0),
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 }},
new Object[] { new IntTuple(CITY, 0), // CITY_THREE_ROAD
new IntTuple(GRASS, 0),
new int[] { 0, 4, 1, 3, 2, 3, 2, 4 },
new IntTuple(GRASS, 1),
new int[] { 2, 4, 2, 3, 3, 3, 4, 4 },
new IntTuple(ROAD, 0),
new int[] { 2, 3, 2, 4 }},
new Object[] { new IntTuple(CITY, 0), // CITY_TWO
new IntTuple(GRASS, 0),
new int[] { 0, 4, 4, 0, 4, 4 }},
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ROAD
new IntTuple(GRASS, 0),
new int[] { 0, 4, 4, 0, 4, 2, 2, 4 },
new IntTuple(ROAD, 0),
new int[] { 2, 4, 4, 2 },
new IntTuple(GRASS, 0),
new int[] { 2, 4, 4, 2, 4, 4 }},
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ACROSS
new IntTuple(GRASS, 0),
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 },
new IntTuple(GRASS, 1),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
new IntTuple(CITY, 1),
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO_ACROSS
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 1, 3, 0, 4 },
new IntTuple(CITY, 1),
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_RIGHT
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
new IntTuple(ROAD, 0),
new int[] { 2, 2, 2, 4 },
new IntTuple(ROAD, 0),
new int[] { 2, 2, 4, 2 }},
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_LEFT
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
new IntTuple(ROAD, 0),
new int[] { 2, 2, 2, 4 },
new IntTuple(ROAD, 0),
new int[] { 0, 2, 2, 2 }},
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_TEE
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
new IntTuple(ROAD, 0),
new int[] { 0, 2, 2, 2 },
new IntTuple(ROAD, 1),
new int[] { 2, 2, 4, 2 },
new IntTuple(ROAD, 2),
new int[] { 2, 2, 2, 4 }},
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_STRAIGHT
new IntTuple(CITY, 0),
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
new IntTuple(ROAD, 0),
new int[] { 0, 2, 4, 2 }},
new Object[] { new IntTuple(GRASS, 0), // CLOISTER
new IntTuple(CITY, 0),
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 }},
new Object[] { new IntTuple(GRASS, 0), // CLOISTER_ROAD
new IntTuple(CITY, 0),
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 },
new IntTuple(ROAD, 0),
new int[] { 2, 3, 2, 4 }},
new Object[] { new IntTuple(GRASS, 0), // FOUR_WAY_ROAD
new IntTuple(ROAD, 0),
new int[] { 2, 0, 2, 2 },
new IntTuple(ROAD, 1),
new int[] { 2, 2, 4, 2 },
new IntTuple(ROAD, 2),
new int[] { 2, 2, 2, 4 },
new IntTuple(ROAD, 3),
new int[] { 0, 2, 2, 2 }},
new Object[] { new IntTuple(GRASS, 0), // THREE_WAY_ROAD
new IntTuple(ROAD, 0),
new int[] { 0, 2, 2, 2 },
new IntTuple(ROAD, 1),
new int[] { 2, 2, 4, 2 },
new IntTuple(ROAD, 2),
new int[] { 2, 2, 2, 4 }},
new Object[] { new IntTuple(GRASS, 0), // STRAIGHT_ROAD
new IntTuple(ROAD, 0),
new int[] { 2, 0, 2, 4 }},
new Object[] { new IntTuple(GRASS, 0), // CURVED_ROAD
new IntTuple(ROAD, 0),
new int[] { 2, 2, 2, 4 },
new IntTuple(ROAD, 0),
new int[] { 0, 2, 2, 2 }},
};
}