diff --git a/src/java/com/threerings/media/sprite/Sprite.java b/src/java/com/threerings/media/sprite/Sprite.java
index 5a0cbf5e4..7140180be 100644
--- a/src/java/com/threerings/media/sprite/Sprite.java
+++ b/src/java/com/threerings/media/sprite/Sprite.java
@@ -1,9 +1,10 @@
//
-// $Id: Sprite.java,v 1.5 2001/08/02 18:59:00 shaper Exp $
+// $Id: Sprite.java,v 1.6 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.sprite;
import java.awt.*;
+import java.util.Enumeration;
import com.threerings.miso.Log;
import com.threerings.miso.tile.Tile;
@@ -62,14 +63,11 @@ public class Sprite
updateDrawPosition();
_curFrame = 0;
- _animDelay = -1;
+ _animDelay = ANIM_NONE;
_numTicks = 0;
setTiles(_tiles);
- _dest = new Point();
- _state = STATE_NONE;
-
invalidate();
}
@@ -124,30 +122,53 @@ public class Sprite
}
/**
- * Set the destination of the sprite in pixel coordinates.
+ * Set the sprite's active path and start moving it along its
+ * merry way. If the sprite is already moving along a previous
+ * path the old path will be lost and the new path will begin to
+ * be traversed.
*
- * @param x the destination x-position.
- * @param y the destination y-position.
+ * @param path the path to follow.
*/
- public void setDestination (int x, int y)
+ public void move (Path path)
{
- // bail if we're already there
- if (x == this.x && y == this.y) return;
+ // make sure following the path is a sensible thing to do
+ if (path == null || path.size() < 2) return;
- // note our destination
- _dest.setLocation(x, y);
+ // save an enumeration of the path nodes
+ _path = path.elements();
+
+ // skip the first node since it's our starting position.
+ // perhaps someday we'll do something with this.
+ _path.nextElement();
+
+ // start our meandering
+ moveAlongPath();
+ }
+
+ /**
+ * Start the sprite moving toward the next node in its path.
+ */
+ protected void moveAlongPath ()
+ {
+ // grab the next node in our path
+ _dest = (PathNode)_path.nextElement();
+
+ // if no more nodes remain, clear out our path and bail
+ if (_dest == null) {
+ _path = null;
+ return;
+ }
+
+ Log.info("moveAlongPath [dest=" + _dest + "].");
// determine the horizontal/vertical move increments
- float dist = MathUtil.distance(this.x, this.y, x, y);
- _incx = (float)(x - this.x) / dist;
- _incy = (float)(y - this.y) / dist;
+ float dist = MathUtil.distance(x, y, _dest.loc.x, _dest.loc.y);
+ _incx = (float)(_dest.loc.x - x) / dist;
+ _incy = (float)(_dest.loc.y - y) / dist;
// init position data used to track fractional pixels
- _movex = this.x;
- _movey = this.y;
-
- // and that we're moving toward it
- _state = STATE_MOVING;
+ _movex = x;
+ _movey = y;
}
/**
@@ -157,13 +178,10 @@ public class Sprite
{
if (_curTile == null) return;
- int xpos = x - (_curTile.width / 2);
- int ypos = y - _curTile.height;
+ Rectangle dirty = new Rectangle(
+ _drawx, _drawy, _curTile.width, _curTile.height);
- Rectangle dirty =
- new Rectangle(xpos, ypos, _curTile.width, _curTile.height);
-
-// Log.info("Sprite dirtying rect [x=" + dirty.x + ", y=" + dirty.y +
+// Log.info("Sprite invalidate [x=" + dirty.x + ", y=" + dirty.y +
// ", width=" + dirty.width + ", height=" + dirty.height + "].");
_spritemgr.addDirtyRect(dirty);
@@ -176,40 +194,49 @@ public class Sprite
public void tick ()
{
// increment the display tile if performing tile animation
- if (_animDelay != -1 && (_numTicks++ == _animDelay)) {
+ if (_animDelay != ANIM_NONE && (_numTicks++ == _animDelay)) {
_numTicks = 0;
if (++_curFrame > _tiles.length - 1) _curFrame = 0;
_curTile = _tiles[_curFrame];
+
+ // dirty our rectangle since we've altered our display tile
invalidate();
}
- switch (_state) {
- case STATE_MOVING:
- // move the sprite incrementally toward its goal
- x = (int)(_movex += _incx);
- y = (int)(_movey += _incy);
-
- // stop moving once we've reached our destination
- if (_incx > 0 && x > _dest.x || _incx < 0 && x < _dest.x ||
- _incy > 0 && y > _dest.y || _incy < 0 && y < _dest.y) {
-
- // make sure we stop exactly where desired
- x = _dest.x;
- y = _dest.y;
-
- // invalidate the sprite in its new location
- invalidate();
-
- // note our stoppage
- _animDelay = -1;
- _state = STATE_NONE;
- }
-
- updateDrawPosition();
- break;
+ // move the sprite along toward its destination, if any
+ if (_dest != null) {
+ handleMove();
}
}
+ /**
+ * Actually move the sprite's position toward its destination one
+ * display increment.
+ */
+ protected void handleMove ()
+ {
+ // move the sprite incrementally toward its goal
+ x = (int)(_movex += _incx);
+ y = (int)(_movey += _incy);
+
+ // stop moving once we've reached our destination
+ if (_incx > 0 && x > _dest.loc.x || _incx < 0 && x < _dest.loc.x ||
+ _incy > 0 && y > _dest.loc.y || _incy < 0 && y < _dest.loc.y) {
+
+ // make sure we stop exactly where desired
+ x = _dest.loc.x;
+ y = _dest.loc.y;
+
+ // dirty our rectangle since we've moved
+ invalidate();
+
+ // move further along the path if necessary
+ moveAlongPath();
+ }
+
+ updateDrawPosition();
+ }
+
/**
* Update the coordinates at which the sprite image is drawn to
* reflect the sprite's current position.
@@ -238,9 +265,8 @@ public class Sprite
return buf.append("]").toString();
}
- /** State constants. */
- protected static final int STATE_NONE = 0;
- protected static final int STATE_MOVING = 1;
+ /** Value used to denote that no tile animation is desired. */
+ protected static final int ANIM_NONE = -1;
/** The tiles used to render the sprite. */
protected Tile[] _tiles;
@@ -254,11 +280,11 @@ public class Sprite
/** The coordinates at which the tile image is drawn. */
protected int _drawx, _drawy;
- /** The sprite's current state. */
- protected int _state;
+ /** The PathNode objects describing the path the sprite is following. */
+ protected Enumeration _path;
- /** When moving, the sprite's destination coordinates. */
- protected Point _dest;
+ /** When moving, the sprite's destination path node. */
+ protected PathNode _dest;
/** When moving, the sprite position including fractional pixels. */
protected float _movex, _movey;
diff --git a/src/java/com/threerings/media/util/LineSegmentPath.java b/src/java/com/threerings/media/util/LineSegmentPath.java
index 60e07c689..f1c169708 100644
--- a/src/java/com/threerings/media/util/LineSegmentPath.java
+++ b/src/java/com/threerings/media/util/LineSegmentPath.java
@@ -1,5 +1,5 @@
//
-// $Id: LineSegmentPath.java,v 1.1 2001/08/02 00:42:02 shaper Exp $
+// $Id: LineSegmentPath.java,v 1.2 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.sprite;
@@ -9,7 +9,9 @@ import java.util.Enumeration;
/**
* The Path class represents the path a sprite follows while
* meandering about the screen. There must be at least two nodes in
- * any worthwhile path.
+ * any worthwhile path. The direction of the first node in the path
+ * is meaningless since the sprite begins at that node and will
+ * therefore never be heading towards it.
*/
public class Path
{
@@ -34,6 +36,15 @@ public class Path
_nodes = new ArrayList();
}
+ public Path (int x, int y)
+ {
+ _nodes = new ArrayList();
+
+ // add the starting node with an arbitrarily chosen direction
+ // since direction is meaningless here
+ addNode(x, y, DIR_NORTH);
+ }
+
/**
* Add a node to the path with the specified destination point and
* facing direction.
@@ -47,6 +58,19 @@ public class Path
_nodes.add(new PathNode(x, y, dir));
}
+ /**
+ * Return the requested node index in the path, or null if no such
+ * index exists.
+ *
+ * @param idx the node index.
+ *
+ * @return the path node.
+ */
+ public PathNode getNode (int idx)
+ {
+ return (PathNode)_nodes.get(idx);
+ }
+
/**
* Return an enumeration of the PathNode objects in this path.
*/
@@ -81,7 +105,7 @@ public class Path
public Object nextElement ()
{
- return _nodes.get(_idx++);
+ return (_idx >= _nodes.size()) ? null : _nodes.get(_idx++);
}
protected ArrayList _nodes;
diff --git a/src/java/com/threerings/media/util/PathNode.java b/src/java/com/threerings/media/util/PathNode.java
index 65b6cb1f4..a59e2d19a 100644
--- a/src/java/com/threerings/media/util/PathNode.java
+++ b/src/java/com/threerings/media/util/PathNode.java
@@ -1,5 +1,5 @@
//
-// $Id: PathNode.java,v 1.1 2001/08/02 00:42:02 shaper Exp $
+// $Id: PathNode.java,v 1.2 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.sprite;
@@ -28,4 +28,16 @@ public class PathNode
loc = new Point(x, y);
this.dir = dir;
}
+
+ /**
+ * Return a string representation of this path node.
+ */
+ public String toString ()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("[x=").append(loc.x);
+ buf.append(", y=").append(loc.y);
+ buf.append(", dir=").append(dir);
+ return buf.append("]").toString();
+ }
}
diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java
index e5c4cc0f4..baf80c6cd 100644
--- a/src/java/com/threerings/miso/client/IsoSceneView.java
+++ b/src/java/com/threerings/miso/client/IsoSceneView.java
@@ -1,10 +1,10 @@
//
-// $Id: IsoSceneView.java,v 1.22 2001/08/02 18:58:59 shaper Exp $
+// $Id: IsoSceneView.java,v 1.23 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.scene;
import com.threerings.miso.Log;
-import com.threerings.miso.sprite.SpriteManager;
+import com.threerings.miso.sprite.*;
import com.threerings.miso.tile.Tile;
import com.threerings.miso.tile.TileManager;
import com.threerings.miso.util.MathUtil;
@@ -69,6 +69,9 @@ public class IsoSceneView implements EditableSceneView
// draw lines illustrating tracking of the mouse position
//paintMouseLines(gfx);
+ gfx.setColor(Color.yellow);
+ gfx.drawRect(0, 0, _model.bounds.width - 1, _model.bounds.height - 1);
+
// restore the original clipping region
gfx.setClip(oldclip);
}
@@ -89,12 +92,12 @@ public class IsoSceneView implements EditableSceneView
int[] dinfo = (int[])_dirty.remove(0);
int tx = dinfo[0], ty = dinfo[1];
+ // get the tile's screen position
+ Polygon poly = getTilePolygon(tx, ty);
+
// draw all layers at this tile position
for (int kk = 0; kk < Scene.NUM_LAYERS; kk++) {
- // get the tile's screen position
- Polygon poly = getTilePolygon(tx, ty);
-
// get the tile at these coordinates and layer
Tile tile = _scene.tiles[tx][ty][kk];
if (tile == null) continue;
@@ -108,7 +111,7 @@ public class IsoSceneView implements EditableSceneView
}
// draw all sprites residing in the current tile
- _spritemgr.renderSprites(gfx, getTilePolygon(tx, ty));
+ _spritemgr.renderSprites(gfx, poly);
}
}
@@ -386,6 +389,21 @@ public class IsoSceneView implements EditableSceneView
_model.calculateXAxis();
}
+ public Path getPath (Sprite sprite, int x, int y)
+ {
+ // make sure the destination point is within our bounds
+ if (x < 0 || x >= _model.bounds.width ||
+ y < 0 || y >= _model.bounds.height) {
+ return null;
+ }
+
+ // create path from current loc to destination
+ Path path = new Path(sprite.x, sprite.y);
+ path.addNode(x, y, Path.DIR_NORTH);
+
+ return path;
+ }
+
/** The color to draw the highlighted tile. */
protected static final Color HLT_COLOR = Color.green;
diff --git a/src/java/com/threerings/miso/client/SceneView.java b/src/java/com/threerings/miso/client/SceneView.java
index 07d8cda50..23e5a0cd4 100644
--- a/src/java/com/threerings/miso/client/SceneView.java
+++ b/src/java/com/threerings/miso/client/SceneView.java
@@ -1,14 +1,16 @@
//
-// $Id: SceneView.java,v 1.8 2001/08/02 00:42:02 shaper Exp $
+// $Id: SceneView.java,v 1.9 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.scene;
-import com.threerings.miso.tile.Tile;
-
import java.awt.Component;
import java.awt.Graphics;
import java.util.ArrayList;
+import com.threerings.miso.sprite.Path;
+import com.threerings.miso.sprite.Sprite;
+import com.threerings.miso.tile.Tile;
+
/**
* The SceneView interface provides an interface to be implemented by
* classes that provide a view of a given scene by drawing the scene
@@ -37,4 +39,17 @@ public interface SceneView
* @param rects the list of java.awt.Rectangle objects.
*/
public void invalidateRects (ArrayList rects);
+
+ /**
+ * Return a Path object detailing a valid path for the given
+ * sprite to take in the scene to get from its current position to
+ * the destination position.
+ *
+ * @param sprite the sprite to move.
+ * @param x the destination x-position in pixel coordinates.
+ * @param y the destination y-position in pixel coordinates.
+ *
+ * @return the sprite's path or null if no valid path exists.
+ */
+ public Path getPath (Sprite sprite, int x, int y);
}
diff --git a/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java
index 4d45af2db..ea26206d8 100644
--- a/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java
+++ b/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java
@@ -1,5 +1,5 @@
//
-// $Id: SceneViewPanel.java,v 1.6 2001/08/02 18:59:00 shaper Exp $
+// $Id: SceneViewPanel.java,v 1.7 2001/08/02 20:43:03 shaper Exp $
package com.threerings.miso.viewer;
@@ -18,8 +18,9 @@ import com.threerings.miso.util.PerformanceMonitor;
import com.threerings.miso.util.PerformanceObserver;
/**
- * The SceneViewPanel class is responsible for managing a SceneView,
- * rendering it to the screen, and handling view-related UI events.
+ * The SceneViewPanel class is responsible for managing a
+ * SceneView, rendering it to the screen, and handling
+ * view-related UI events.
*/
public class SceneViewPanel extends JPanel
implements MouseListener, MouseMotionListener, PerformanceObserver
@@ -53,7 +54,7 @@ public class SceneViewPanel extends JPanel
// load up the initial scene
prepareStartingScene();
- setDoubleBuffered(false);
+ //setDoubleBuffered(false);
PerformanceMonitor.register(this, "paint", 1000);
}
@@ -100,9 +101,6 @@ public class SceneViewPanel extends JPanel
_view.paint(g);
- g.setColor(Color.yellow);
- g.drawRect(0, 0, 600, 600);
-
PerformanceMonitor.tick(this, "paint");
}
@@ -113,34 +111,30 @@ public class SceneViewPanel extends JPanel
/** MouseListener interface methods */
- public void mouseClicked (MouseEvent e)
- {
- Log.info("mouseClicked [x=" + e.getX() + ", y=" + e.getY() + "].");
- }
-
- public void mouseEntered (MouseEvent e) { }
-
- public void mouseExited (MouseEvent e) { }
-
public void mousePressed (MouseEvent e)
{
int x = e.getX(), y = e.getY();
Log.info("mousePressed [x=" + x + ", y=" + y + "].");
- _sprite.setDestination(x, y);
+
+ // get the path from here to there
+ Path path = _view.getPath(_sprite, x, y);
+ if (path != null) {
+ _sprite.move(path);
+ }
+
+ // hackily highlight the tile that was clicked on for happy testing
((EditableSceneView)_view).setHighlightedTile(x, y);
}
+ public void mouseClicked (MouseEvent e) { }
+ public void mouseEntered (MouseEvent e) { }
+ public void mouseExited (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
/** MouseMotionListener interface methods */
- public void mouseMoved (MouseEvent e)
- {
- }
-
- public void mouseDragged (MouseEvent e)
- {
- }
+ public void mouseMoved (MouseEvent e) { }
+ public void mouseDragged (MouseEvent e) { }
/** The config key to obtain the default scene filename. */
protected static final String CFG_SCENE = "miso-viewer.default_scene";
@@ -148,6 +142,7 @@ public class SceneViewPanel extends JPanel
/** The default scene to load and display. */
protected static final String DEF_SCENE = "rsrc/scenes/default.xml";
+ /** The sprite we're manipulating within the view. */
protected Sprite _sprite;
/** The context object. */