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:
@@ -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 }},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user