Added row-based tile width, image offset, and image row/column gap

distance parameters to tile sets.  Removed constant tile width/height
references except, for now, for isometric tile rendering which still
requires tiles that are 32x16.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@130 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Walter Korman
2001-07-28 01:31:51 +00:00
parent e9ab0b343b
commit 92e46c6eae
8 changed files with 175 additions and 118 deletions
+5 -12
View File
@@ -1,5 +1,5 @@
//
// $Id: Tile.java,v 1.7 2001/07/23 18:52:51 shaper Exp $
// $Id: Tile.java,v 1.8 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.tile;
@@ -19,18 +19,11 @@ public class Tile
/** The tile identifier within the set. */
public short tid;
/** The tile width in pixels. */
public short width;
/** The tile height in pixels. */
public short height; // the tile height in pixels
/** The height and width of a tile image in pixels. */
public static final int HEIGHT = 16;
public static final int WIDTH = 32;
/** Halved tile width in pixels for use in common calculations. */
public static final int HALF_HEIGHT = HEIGHT / 2;
/** Halved tile height in pixels for use in common calculations. */
public static final int HALF_WIDTH = WIDTH / 2;
public short height;
/**
* Construct a new tile with the specified identifiers. Intended
@@ -1,5 +1,5 @@
//
// $Id: TileManager.java,v 1.11 2001/07/23 22:31:48 shaper Exp $
// $Id: TileManager.java,v 1.12 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.tile;
@@ -46,7 +46,9 @@ public class TileManager
if ((tile.img = _tilesetmgr.getTileImage(tsid, tid)) == null) {
Log.warning("Null tile image [tsid="+tsid+", tid="+tid+"].");
}
tile.height = (short)((BufferedImage)tile.img).getHeight();
BufferedImage bimg = (BufferedImage)tile.img;
tile.height = (short)bimg.getHeight();
tile.width = (short)bimg.getWidth();
_tiles.put(utid, tile);
+47 -15
View File
@@ -1,9 +1,10 @@
//
// $Id: TileSet.java,v 1.10 2001/07/23 18:52:51 shaper Exp $
// $Id: TileSet.java,v 1.11 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.tile;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.*;
import com.samskivert.util.StringUtil;
@@ -15,11 +16,6 @@ import com.threerings.media.ImageManager;
* provides a clean interface for the TileManager to retrieve
* individual tile images from a particular tile in the tileset.
*
* <p> The width of each tile in every tileset is a constant
* <code>Tile.WIDTH</code> in pixels. The tile count in each row can
* vary. The height of the tiles in each row can also vary. This
* information is obtained from the config object.
*
* <p> Tiles are retrieved from the tile set by the TileManager, and
* are referenced by their tile id (essentially the tile number,
* assuming the tile at the top-left of the image is tile id 0 and
@@ -32,13 +28,17 @@ public class TileSet
* Construct a new TileSet object with the given parameters.
*/
public TileSet (String name, int tsid, String imgFile,
int[] rowHeight, int[] tileCount)
int[] rowWidth, int[] rowHeight, int[] tileCount,
Point offsetPos, Point gapDist)
{
_name = name;
_tsid = tsid;
_imgFile = imgFile;
_rowWidth = rowWidth;
_rowHeight = rowHeight;
_tileCount = tileCount;
_offsetPos = offsetPos;
_gapDist = gapDist;
// determine the total number of tiles in the set
for (int ii = 0; ii < _tileCount.length; ii++)
@@ -86,22 +86,30 @@ public class TileSet
// find the row number containing the sought-after tile
int ridx, tcount, ty, tx;
ridx = tcount = ty = tx = 0;
ridx = tcount = 0;
// start tile image position at image start offset
tx = _offsetPos.x;
ty = _offsetPos.y;
while ((tcount += _tileCount[ridx]) < tid + 1) {
ty += _rowHeight[ridx++];
// increment tile image position by row height and gap distance
ty += (_rowHeight[ridx++] + _gapDist.y);
}
// determine the horizontal index of this tile in the row
int xidx = tid - (tcount - _tileCount[ridx]);
tx = Tile.WIDTH * xidx;
// Log.info("Retrieving tile image [tid=" + tid + ", ridx=" +
// ridx + ", xidx=" + xidx + ", tx=" + tx +
// ", ty=" + ty + "].");
// final image x-position is based on tile width and gap distance
tx += (xidx * (_rowWidth[ridx] + _gapDist.x));
Log.info("Retrieving tile image [tid=" + tid + ", ridx=" +
ridx + ", xidx=" + xidx + ", tx=" + tx +
", ty=" + ty + "].");
// crop the tile-sized image chunk from the full image
return imgr.getImageCropped(_imgTiles, tx, ty,
Tile.WIDTH, _rowHeight[ridx]);
return imgr.getImageCropped(
_imgTiles, tx, ty, _rowWidth[ridx], _rowHeight[ridx]);
}
/**
@@ -116,12 +124,21 @@ public class TileSet
buf.append(", tsid=").append(_tsid);
buf.append(", numtiles=").append(_numTiles);
buf.append(", rowwidth=");
StringUtil.toString(buf, _rowWidth);
buf.append(", rowheight=");
StringUtil.toString(buf, _rowHeight);
buf.append(", tilecount=");
StringUtil.toString(buf, _tileCount);
buf.append(", offsetpos=(").append(_offsetPos.x);
buf.append(", ").append(_offsetPos.y).append(")");
buf.append(", gapdist=(").append(_gapDist.x);
buf.append(", ").append(_gapDist.y).append(")");
return buf.append("]").toString();
}
@@ -134,12 +151,27 @@ public class TileSet
/** The tileset unique identifier. */
protected int _tsid;
/** The width of the tiles in each row in pixels. */
protected int _rowWidth[];
/** The height of each row in pixels. */
protected int _rowHeight[];
/** The number of tiles in each row. */
protected int _tileCount[];
/**
* The offset distance (x, y) in pixels from the top-left of the
* image to the start of the first tile image.
*/
protected Point _offsetPos;
/**
* The distance (x, y) in pixels between each tile in each row
* horizontally, and between each row of tiles vertically.
*/
protected Point _gapDist;
/** The total number of tiles. */
protected int _numTiles;
@@ -1,8 +1,9 @@
//
// $Id: XMLTileSetParser.java,v 1.7 2001/07/24 22:52:02 shaper Exp $
// $Id: XMLTileSetParser.java,v 1.8 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.tile;
import java.awt.Point;
import java.io.*;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
@@ -34,8 +35,13 @@ public class XMLTileSetParser extends DefaultHandler
// construct the tileset object on tag close
if (qName.equals("tileset")) {
TileSet tset = new TileSet(
_tsName, _tsTsid, _tsImgFile, _tsRowHeight, _tsTileCount);
_tsName, _tsTsid, _tsImgFile, _tsRowWidth, _tsRowHeight,
_tsTileCount, _tsOffsetPos, _tsGapDist);
_tilesets.add(tset);
// prepare to read another tileset object
init();
}
// note that we're not within a tag to avoid considering any
@@ -66,11 +72,20 @@ public class XMLTileSetParser extends DefaultHandler
} else if (_tag.equals("imagefile")) {
_tsImgFile = str;
} else if (_tag.equals("rowwidth")) {
_tsRowWidth = StringUtil.parseIntArray(str);
} else if (_tag.equals("rowheight")) {
_tsRowHeight = StringUtil.parseIntArray(str);
} else if (_tag.equals("tilecount")) {
_tsTileCount = StringUtil.parseIntArray(str);
} else if (_tag.equals("offsetpos")) {
getPoint(str, _tsOffsetPos);
} else if (_tag.equals("gapdist")) {
getPoint(str, _tsGapDist);
}
}
@@ -83,6 +98,9 @@ public class XMLTileSetParser extends DefaultHandler
return _tilesets;
}
// prepare to read a new tileset
init();
// read all tileset descriptions from the XML input stream
XMLUtil.parse(this, tis);
@@ -96,6 +114,30 @@ public class XMLTileSetParser extends DefaultHandler
}
}
/**
* Initialize internal member data used to gather tileset
* information during parsing.
*/
protected void init ()
{
_tsOffsetPos = new Point();
_tsGapDist = new Point();
}
/**
* Converts a string containing values as (x, y) into the
* corresponding integer values and populates the given point
* object.
*
* @param str the point values in string format.
* @param point the point object to populate.
*/
protected void getPoint (String str, Point point)
{
int vals[] = StringUtil.parseIntArray(str);
point.setLocation(vals[0], vals[1]);
}
/** The XML element tag currently being processed. */
protected String _tag;
@@ -106,5 +148,6 @@ public class XMLTileSetParser extends DefaultHandler
protected String _tsName;
protected int _tsTsid;
protected String _tsImgFile;
protected int[] _tsRowHeight, _tsTileCount;
protected int[] _tsRowWidth, _tsRowHeight, _tsTileCount;
protected Point _tsOffsetPos, _tsGapDist;
}
@@ -1,5 +1,5 @@
//
// $Id: IsoSceneView.java,v 1.16 2001/07/27 17:54:08 shaper Exp $
// $Id: IsoSceneView.java,v 1.17 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.scene;
@@ -27,7 +27,7 @@ public class IsoSceneView implements EditableSceneView
{
_tmgr = tmgr;
_bounds = new Rectangle(0, 0, DEF_BOUNDS_WIDTH, DEF_BOUNDS_HEIGHT);
_bounds = new Dimension(DEF_BOUNDS_WIDTH, DEF_BOUNDS_HEIGHT);
_htile = new Point();
_htile.x = _htile.y = -1;
@@ -96,7 +96,7 @@ public class IsoSceneView implements EditableSceneView
int length = (ty - tx) + 1;
// determine starting screen x-position
int screenX = DEF_CENTER_X - ((length) * Tile.HALF_WIDTH);
int screenX = DEF_CENTER_X - ((length) * ISO_TILE_HALFWIDTH);
for (int jj = 0; jj < length; jj++) {
@@ -107,7 +107,7 @@ public class IsoSceneView implements EditableSceneView
// determine screen y-position, accounting for
// tile image height
int ypos = screenY - (tile.height - Tile.HEIGHT);
int ypos = screenY - (tile.height - ISO_TILE_HEIGHT);
// draw the tile image at the appropriate screen position
gfx.drawImage(tile.img, screenX, ypos, null);
@@ -117,7 +117,7 @@ public class IsoSceneView implements EditableSceneView
if (_showCoords) paintCoords(gfx, tx, ty, screenX, screenY);
// each tile is one tile-width to the right of the previous
screenX += Tile.WIDTH;
screenX += ISO_TILE_WIDTH;
// advance tile x and decrement tile y as we move to
// the right drawing the row
@@ -126,7 +126,7 @@ public class IsoSceneView implements EditableSceneView
}
// each row is a half-tile-height away from the previous row
screenY += Tile.HALF_HEIGHT;
screenY += ISO_TILE_HALFHEIGHT;
// advance starting y-axis coordinate unless we've hit bottom
if ((++my) > Scene.TILE_HEIGHT - 1) my = Scene.TILE_HEIGHT - 1;
@@ -170,8 +170,10 @@ public class IsoSceneView implements EditableSceneView
{
gfx.setFont(_font);
gfx.setColor(Color.white);
gfx.drawString(""+x, sx+Tile.HALF_WIDTH-2, sy+Tile.HALF_HEIGHT-2);
gfx.drawString(""+y, sx+Tile.HALF_WIDTH-2, sy+Tile.HEIGHT-2);
gfx.drawString("" + x, sx + ISO_TILE_HALFWIDTH - 2,
sy + ISO_TILE_HALFHEIGHT - 2);
gfx.drawString("" + y, sx + ISO_TILE_HALFWIDTH - 2,
sy + ISO_TILE_HEIGHT - 2);
}
/**
@@ -193,14 +195,14 @@ public class IsoSceneView implements EditableSceneView
gfx.setColor(HLT_COLOR);
// draw the tile outline
gfx.drawLine(spos.x, spos.y + Tile.HALF_HEIGHT,
spos.x + Tile.HALF_WIDTH, spos.y);
gfx.drawLine(spos.x + Tile.HALF_WIDTH, spos.y,
spos.x + Tile.WIDTH, spos.y + Tile.HALF_HEIGHT);
gfx.drawLine(spos.x + Tile.WIDTH, spos.y + Tile.HALF_HEIGHT,
spos.x + Tile.HALF_WIDTH, spos.y + Tile.HEIGHT);
gfx.drawLine(spos.x + Tile.HALF_WIDTH, spos.y + Tile.HEIGHT,
spos.x, spos.y + Tile.HALF_HEIGHT);
gfx.drawLine(spos.x, spos.y + ISO_TILE_HALFHEIGHT,
spos.x + ISO_TILE_HALFWIDTH, spos.y);
gfx.drawLine(spos.x + ISO_TILE_HALFWIDTH, spos.y,
spos.x + ISO_TILE_WIDTH, spos.y + ISO_TILE_HALFHEIGHT);
gfx.drawLine(spos.x + ISO_TILE_WIDTH, spos.y + ISO_TILE_HALFHEIGHT,
spos.x + ISO_TILE_HALFWIDTH, spos.y + ISO_TILE_HEIGHT);
gfx.drawLine(spos.x + ISO_TILE_HALFWIDTH, spos.y + ISO_TILE_HEIGHT,
spos.x, spos.y + ISO_TILE_HALFHEIGHT);
// restore the original stroke
gfx.setStroke(ostroke);
@@ -231,7 +233,7 @@ public class IsoSceneView implements EditableSceneView
_lineX[0].y = DEF_CENTER_Y;
// determine the ending point
_lineX[1].x = _lineX[0].x + (Tile.HALF_WIDTH * Scene.TILE_WIDTH);
_lineX[1].x = _lineX[0].x + (ISO_TILE_HALFWIDTH * Scene.TILE_WIDTH);
_lineX[1].y = _lineX[0].y + (int)((SLOPE_X * _lineX[1].x) + _bX);
}
@@ -277,8 +279,8 @@ public class IsoSceneView implements EditableSceneView
*/
protected void tileToScreen (int x, int y, Point spos)
{
spos.x = _lineX[0].x + ((x - y - 1) * Tile.HALF_WIDTH);
spos.y = _lineX[0].y + ((x + y) * Tile.HALF_HEIGHT);
spos.x = _lineX[0].x + ((x - y - 1) * ISO_TILE_HALFWIDTH);
spos.y = _lineX[0].y + ((x + y) * ISO_TILE_HALFHEIGHT);
}
public void setScene (Scene scene)
@@ -298,11 +300,17 @@ public class IsoSceneView implements EditableSceneView
_scene.tiles[tpos.x][tpos.y][lnum] = tile;
}
protected static final int ISO_TILE_HEIGHT = 16;
protected static final int ISO_TILE_WIDTH = 32;
protected static final int ISO_TILE_HALFHEIGHT = ISO_TILE_HEIGHT / 2;
protected static final int ISO_TILE_HALFWIDTH = ISO_TILE_WIDTH / 2;
/** The default width of a scene in pixels. */
protected static final int DEF_BOUNDS_WIDTH = 18 * Tile.WIDTH;
protected static final int DEF_BOUNDS_WIDTH = 18 * ISO_TILE_WIDTH;
/** The default height of a scene in pixels. */
protected static final int DEF_BOUNDS_HEIGHT = 37 * Tile.HEIGHT;
protected static final int DEF_BOUNDS_HEIGHT = 37 * ISO_TILE_HEIGHT;
/** The total number of tile rows to render the full scene view. */
protected static final int TILE_RENDER_ROWS =
@@ -312,12 +320,12 @@ public class IsoSceneView implements EditableSceneView
protected static final int DEF_CENTER_X = DEF_BOUNDS_WIDTH / 2;
/** The starting y-position to render the view. */
protected static final int DEF_CENTER_Y = -(9 * Tile.HEIGHT);
protected static final int DEF_CENTER_Y = -(9 * ISO_TILE_HEIGHT);
/** The length of a tile edge in pixels from an isometric perspective. */
protected static final float TILE_EDGE_LENGTH = (float)
Math.sqrt((Tile.HALF_WIDTH * Tile.HALF_WIDTH) +
(Tile.HALF_HEIGHT * Tile.HALF_HEIGHT));
Math.sqrt((ISO_TILE_HALFWIDTH * ISO_TILE_HALFWIDTH) +
(ISO_TILE_HALFHEIGHT * ISO_TILE_HALFHEIGHT));
/** The color to draw the highlighted tile. */
protected static final Color HLT_COLOR = Color.green;
@@ -337,8 +345,8 @@ public class IsoSceneView implements EditableSceneView
/** The last calculated x- and y-axis mouse position tracking lines. */
protected Point _lineX[], _lineY[];
/** The bounds rectangle for the view. */
protected Rectangle _bounds;
/** The bounds dimensions for the view. */
protected Dimension _bounds;
/** The currently highlighted tile. */
protected Point _htile;
@@ -1,5 +1,5 @@
//
// $Id: SceneViewPanel.java,v 1.1 2001/07/25 17:38:15 shaper Exp $
// $Id: SceneViewPanel.java,v 1.2 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.viewer;
@@ -27,19 +27,33 @@ public class SceneViewPanel extends JPanel
public SceneViewPanel (ViewerContext ctx)
{
_ctx = ctx;
// construct the view object
_view = new IsoSceneView(_ctx.getTileManager());
// listen to the desired events
addMouseListener(this);
addMouseMotionListener(this);
// load up the initial scene
prepareStartingScene();
}
/**
* Load and set up the starting scene for display.
*/
protected void prepareStartingScene ()
{
// get the scene repository
XMLFileSceneRepository repo = (XMLFileSceneRepository)
_ctx.getSceneManager().getSceneRepository();
// load the starting scene
// get the starting scene filename
Config config = _ctx.getConfig();
String fname = config.getValue(CONF_SCENE, (String)DEF_SCENE);
try {
// load and set up the scene
_view.setScene(repo.loadScene(fname));
} catch (IOException ioe) {
Log.warning("Exception loading scene [fname=" + fname +
@@ -62,12 +76,14 @@ public class SceneViewPanel extends JPanel
{
super.paint(g);
_view.paint(g);
Log.info("paint()");
}
/** MouseListener interface methods */
public void mouseClicked (MouseEvent e)
{
Log.info("mouseClicked [x=" + e.getX() + ", y=" + e.getY() + "].");
}
public void mouseEntered (MouseEvent e) { }
@@ -76,6 +92,7 @@ public class SceneViewPanel extends JPanel
public void mousePressed (MouseEvent e)
{
Log.info("mousePressed [x=" + e.getX() + ", y=" + e.getY() + "].");
}
public void mouseReleased (MouseEvent e) { }
@@ -1,5 +1,5 @@
//
// $Id: ViewerApp.java,v 1.1 2001/07/25 17:38:15 shaper Exp $
// $Id: ViewerApp.java,v 1.2 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.viewer;
@@ -28,7 +28,7 @@ public class ViewerApp
// create and size the main application frame
_frame = new ViewerFrame();
_frame.setSize(WIDTH, HEIGHT);
// SwingUtil.centerFrame(_frame);
SwingUtil.centerWindow(_frame);
// create the handles on our various services
_config = createConfig();
@@ -1,16 +1,16 @@
//
// $Id: ViewerFrame.java,v 1.1 2001/07/25 17:38:15 shaper Exp $
// $Id: ViewerFrame.java,v 1.2 2001/07/28 01:31:51 shaper Exp $
package com.threerings.miso.viewer;
import com.samskivert.swing.*;
import com.samskivert.swing.util.MenuUtil;
import com.threerings.miso.Log;
import com.threerings.miso.viewer.util.ViewerContext;
import com.threerings.miso.scene.Scene;
import com.threerings.miso.sprite.AnimationManager;
import com.threerings.miso.sprite.SpriteManager;
import com.threerings.miso.viewer.util.ViewerContext;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
@@ -19,7 +19,7 @@ import javax.swing.*;
* contains the application menu bar and panels and responds to menu
* events.
*/
class ViewerFrame extends JFrame implements ActionListener
class ViewerFrame extends JFrame
{
public ViewerFrame ()
{
@@ -33,58 +33,20 @@ class ViewerFrame extends JFrame implements ActionListener
{
_ctx = ctx;
// set up the menu bar
createMenuBar();
// create a top-level panel to manage everything
JPanel top = new JPanel();
GroupLayout gl = new HGroupLayout(GroupLayout.STRETCH);
gl.setOffAxisPolicy(GroupLayout.STRETCH);
top.setLayout(gl);
// set up the scene view panel with a default scene
SceneViewPanel svpanel = new SceneViewPanel(_ctx);
// setScene(new Scene(_tilemgr, Scene.SID_INVALID));
top.add(svpanel);
// now add our top-level panel
getContentPane().add(top, BorderLayout.CENTER);
// create the animation manager for the panel
SpriteManager spritemgr = new SpriteManager();
AnimationManager animmgr = new AnimationManager(spritemgr, svpanel);
// add the scene view panel
getContentPane().add(svpanel, BorderLayout.CENTER);
}
/**
* Create the menu bar and menu items and add them to the frame.
*/
public void createMenuBar ()
{
KeyStroke accel = null;
// create the "File" menu
JMenu menuFile = new JMenu("File");
accel = KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK);
MenuUtil.addMenuItem(this, menuFile, "Quit", KeyEvent.VK_Q, accel);
// create the menu bar
JMenuBar bar = new JMenuBar();
bar.add(menuFile);
// add the menu bar to the frame
setJMenuBar(bar);
}
/**
* Handle menu item selections.
*/
public void actionPerformed (ActionEvent e)
{
String cmd = e.getActionCommand();
if (cmd.equals("Quit")) {
System.exit(0);
} else {
Log.warning("Unknown action command [cmd=" + cmd + "].");
}
}
/** The panel displaying the scene. */
SceneViewPanel _svpanel;
/** The context object. */
protected ViewerContext _ctx;