Fixed up path-finding, path-following, and tile coordinate drawing.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@260 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: CharacterSprite.java,v 1.5 2001/08/15 02:30:27 shaper Exp $
|
// $Id: CharacterSprite.java,v 1.6 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.miso.scene;
|
package com.threerings.miso.scene;
|
||||||
|
|
||||||
@@ -52,8 +52,6 @@ public class AmbulatorySprite extends Sprite implements Traverser
|
|||||||
|
|
||||||
// bail if we're at the end of the path
|
// bail if we're at the end of the path
|
||||||
if (_dest == null) {
|
if (_dest == null) {
|
||||||
// stop any walking animation
|
|
||||||
setAnimationDelay(ANIM_NONE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +62,14 @@ public class AmbulatorySprite extends Sprite implements Traverser
|
|||||||
setAnimationDelay(0);
|
setAnimationDelay(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stop ()
|
||||||
|
{
|
||||||
|
super.stop();
|
||||||
|
|
||||||
|
// stop any walking animation
|
||||||
|
setAnimationDelay(ANIM_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canTraverse (Tile tile)
|
public boolean canTraverse (Tile tile)
|
||||||
{
|
{
|
||||||
// by default, passability is solely the province of the tile
|
// by default, passability is solely the province of the tile
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Sprite.java,v 1.10 2001/08/14 23:35:22 mdb Exp $
|
// $Id: Sprite.java,v 1.11 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.media.sprite;
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
@@ -80,7 +80,26 @@ public class Sprite
|
|||||||
public void paint (Graphics2D gfx)
|
public void paint (Graphics2D gfx)
|
||||||
{
|
{
|
||||||
gfx.drawImage(_frame, _drawx, _drawy, null);
|
gfx.drawImage(_frame, _drawx, _drawy, null);
|
||||||
// Log.info("Sprite painting image [sprite=" + this + "].");
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint the sprite's path, if any, to the specified graphics context.
|
||||||
|
*
|
||||||
|
* @param gfx the graphics context.
|
||||||
|
*/
|
||||||
|
public void paintPath (Graphics2D gfx)
|
||||||
|
{
|
||||||
|
if (_fullpath == null) return;
|
||||||
|
|
||||||
|
gfx.setColor(Color.red);
|
||||||
|
Point prev = null;
|
||||||
|
int size = _fullpath.size();
|
||||||
|
for (int ii = 0; ii < size; ii++) {
|
||||||
|
PathNode n = (PathNode)_fullpath.getNode(ii);
|
||||||
|
if (prev == null) prev = n.loc;
|
||||||
|
gfx.drawLine(prev.x, prev.y, n.loc.x, n.loc.y);
|
||||||
|
prev = n.loc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,6 +141,19 @@ public class Sprite
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the sprite from any movement along a path it may be
|
||||||
|
* engaged in.
|
||||||
|
*/
|
||||||
|
public void stop ()
|
||||||
|
{
|
||||||
|
// TODO: make sure we come to a stop on a full coordinate,
|
||||||
|
// even in the case where we aborted a path walk mid-traversal.
|
||||||
|
_dest = null;
|
||||||
|
_path = null;
|
||||||
|
_fullpath = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the sprite's active path and start moving it along its
|
* Set the sprite's active path and start moving it along its
|
||||||
* merry way. If the sprite is already moving along a previous
|
* merry way. If the sprite is already moving along a previous
|
||||||
@@ -133,12 +165,20 @@ public class Sprite
|
|||||||
public void move (Path path)
|
public void move (Path path)
|
||||||
{
|
{
|
||||||
// make sure following the path is a sensible thing to do
|
// make sure following the path is a sensible thing to do
|
||||||
if (path == null || path.size() < 2) return;
|
if (path == null || path.size() < 2) {
|
||||||
|
// halt movement if we're walking since, regardless of its
|
||||||
|
// reasonableness, we've been asked to follow a new path
|
||||||
|
stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// save an enumeration of the path nodes
|
// save an enumeration of the path nodes
|
||||||
_path = path.elements();
|
_path = path.elements();
|
||||||
|
|
||||||
// skip the first node since it's our starting position.
|
// and the full path for potential rendering
|
||||||
|
_fullpath = path;
|
||||||
|
|
||||||
|
// skip the first node since it's our starting position.
|
||||||
// perhaps someday we'll do something with this.
|
// perhaps someday we'll do something with this.
|
||||||
_path.nextElement();
|
_path.nextElement();
|
||||||
|
|
||||||
@@ -156,7 +196,7 @@ public class Sprite
|
|||||||
|
|
||||||
// if no more nodes remain, clear out our path and bail
|
// if no more nodes remain, clear out our path and bail
|
||||||
if (_dest == null) {
|
if (_dest == null) {
|
||||||
_path = null;
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,11 +228,6 @@ public class Sprite
|
|||||||
Rectangle dirty = new Rectangle(
|
Rectangle dirty = new Rectangle(
|
||||||
_drawx, _drawy, _frame.getWidth(null), _frame.getHeight(null));
|
_drawx, _drawy, _frame.getWidth(null), _frame.getHeight(null));
|
||||||
|
|
||||||
// Log.info("Sprite invalidate [x=" + x + ", y=" + y +
|
|
||||||
// ", dx=" + dirty.x + ", dy=" + dirty.y +
|
|
||||||
// ", dwidth=" + dirty.width +
|
|
||||||
// ", dheight=" + dirty.height + "].");
|
|
||||||
|
|
||||||
_spritemgr.addDirtyRect(dirty);
|
_spritemgr.addDirtyRect(dirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,6 +346,9 @@ public class Sprite
|
|||||||
/** The number of ticks since the last image animation. */
|
/** The number of ticks since the last image animation. */
|
||||||
protected int _numTicks;
|
protected int _numTicks;
|
||||||
|
|
||||||
|
/** When moving, the full path the sprite is traversing. */
|
||||||
|
protected Path _fullpath;
|
||||||
|
|
||||||
/** The sprite manager. */
|
/** The sprite manager. */
|
||||||
protected SpriteManager _spritemgr;
|
protected SpriteManager _spritemgr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SpriteManager.java,v 1.6 2001/08/14 22:54:45 mdb Exp $
|
// $Id: SpriteManager.java,v 1.7 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.media.sprite;
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
@@ -61,19 +61,6 @@ public class SpriteManager
|
|||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a sprite moving along a particular path. The sprite will
|
|
||||||
* continue to be moved along the path until the final destination
|
|
||||||
* is reached, or until the sprite is brought to a halt by some
|
|
||||||
* has-yet-to-be-determined means.
|
|
||||||
*
|
|
||||||
* @param sprite the sprite to move.
|
|
||||||
* @param path the path to move the sprite along.
|
|
||||||
*/
|
|
||||||
public void moveSprite (Sprite sprite, Path path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the sprites residing within the given polygon to the
|
* Render the sprites residing within the given polygon to the
|
||||||
* given graphics context.
|
* given graphics context.
|
||||||
@@ -96,6 +83,20 @@ public class SpriteManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the sprite paths to the given graphics context.
|
||||||
|
*
|
||||||
|
* @param gfx the graphics context.
|
||||||
|
*/
|
||||||
|
public void renderSpritePaths (Graphics2D gfx)
|
||||||
|
{
|
||||||
|
int size = _sprites.size();
|
||||||
|
for (int ii = 0; ii < size; ii++) {
|
||||||
|
Sprite sprite = (Sprite)_sprites.get(ii);
|
||||||
|
sprite.paintPath(gfx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call <code>tick()</code> on all sprite objects to give them a
|
* Call <code>tick()</code> on all sprite objects to give them a
|
||||||
* chance to move themselves about, change their display image,
|
* chance to move themselves about, change their display image,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: IsoSceneView.java,v 1.46 2001/08/15 03:13:06 shaper Exp $
|
// $Id: IsoSceneView.java,v 1.47 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.miso.scene;
|
package com.threerings.miso.scene;
|
||||||
|
|
||||||
@@ -87,6 +87,11 @@ public class IsoSceneView implements EditableSceneView
|
|||||||
clearDirtyRegions();
|
clearDirtyRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw sprite paths
|
||||||
|
if (_model.showPaths) {
|
||||||
|
_spritemgr.renderSpritePaths(gfx);
|
||||||
|
}
|
||||||
|
|
||||||
// draw marks at each location
|
// draw marks at each location
|
||||||
if (_model.showLocs) {
|
if (_model.showLocs) {
|
||||||
paintLocations(gfx);
|
paintLocations(gfx);
|
||||||
@@ -170,7 +175,8 @@ public class IsoSceneView implements EditableSceneView
|
|||||||
|
|
||||||
// paint the tile coordinate if desired
|
// paint the tile coordinate if desired
|
||||||
if (_model.showCoords) {
|
if (_model.showCoords) {
|
||||||
paintCoords(gfx, xx, yy, poly.xpoints[0], poly.ypoints[0]);
|
paintCoords(gfx, xx, yy, poly.xpoints[0],
|
||||||
|
poly.ypoints[0] - _model.tilehhei);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bail early if we know we've drawn all dirty tiles
|
// bail early if we know we've drawn all dirty tiles
|
||||||
@@ -567,6 +573,9 @@ public class IsoSceneView implements EditableSceneView
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make more visually appealing path segments from start
|
||||||
|
// to second tile, and penultimate to ultimate tile.
|
||||||
|
|
||||||
// construct path with starting screen position
|
// construct path with starting screen position
|
||||||
Path path = new Path(sprite.x, sprite.y);
|
Path path = new Path(sprite.x, sprite.y);
|
||||||
|
|
||||||
@@ -589,9 +598,6 @@ public class IsoSceneView implements EditableSceneView
|
|||||||
path.addNode(nspos.x + _model.tilehwid,
|
path.addNode(nspos.x + _model.tilehwid,
|
||||||
nspos.y + _model.tilehhei, dir);
|
nspos.y + _model.tilehhei, dir);
|
||||||
|
|
||||||
// Log.info("Adding node [tx=" + n.x + ", ty=" + n.y +
|
|
||||||
// ", dir=" + dir + "].");
|
|
||||||
|
|
||||||
prev = n;
|
prev = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: IsoSceneViewModel.java,v 1.7 2001/08/15 01:08:49 mdb Exp $
|
// $Id: IsoSceneViewModel.java,v 1.8 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.miso.scene;
|
package com.threerings.miso.scene;
|
||||||
|
|
||||||
@@ -65,6 +65,9 @@ public class IsoSceneModel
|
|||||||
/** Whether locations in the scene should be drawn. */
|
/** Whether locations in the scene should be drawn. */
|
||||||
public boolean showLocs;
|
public boolean showLocs;
|
||||||
|
|
||||||
|
/** Whether sprite paths should be drawn. */
|
||||||
|
public boolean showPaths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an IsoSceneModel with reasonable default values.
|
* Construct an IsoSceneModel with reasonable default values.
|
||||||
*/
|
*/
|
||||||
@@ -126,6 +129,16 @@ public class IsoSceneModel
|
|||||||
showCoords = show;
|
showCoords = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether sprite paths should be drawn.
|
||||||
|
*
|
||||||
|
* @param show whether to show paths.
|
||||||
|
*/
|
||||||
|
public void setShowSpritePaths (boolean show)
|
||||||
|
{
|
||||||
|
showPaths = show;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the dimensions of the tiles that comprise the base layer of
|
* Set the dimensions of the tiles that comprise the base layer of
|
||||||
* the isometric view and therefore drive the view geometry as a
|
* the isometric view and therefore drive the view geometry as a
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: AStarPathUtil.java,v 1.1 2001/08/15 02:30:27 shaper Exp $
|
// $Id: AStarPathUtil.java,v 1.2 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.miso.scene.util;
|
package com.threerings.miso.scene.util;
|
||||||
|
|
||||||
@@ -109,22 +109,27 @@ public class AStarPathUtil
|
|||||||
|
|
||||||
// skip node if it's impassable
|
// skip node if it's impassable
|
||||||
// TODO: fix hard-coded consideration of only the base layer
|
// TODO: fix hard-coded consideration of only the base layer
|
||||||
if (!info.trav.canTraverse(info.tiles[x][y][0])) return;
|
if (!info.trav.canTraverse(info.tiles[x][y][0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// calculate the new cost for this node
|
// calculate the new cost for this node
|
||||||
int newg = n.g + 1; // getCost() is always 1?
|
int newg = n.g + 1; // cost to go node-to-node is always 1 for now
|
||||||
|
|
||||||
// retrieve the node corresponding to this location
|
// retrieve the node corresponding to this location
|
||||||
AStarNode np = getNode(info, x, y);
|
AStarNode np = getNode(info, x, y);
|
||||||
|
|
||||||
// skip if it's already in the open or closed list or if its
|
// skip if it's already in the open or closed list or if its
|
||||||
// actual cost is less than the just-calculated cost
|
// actual cost is less than the just-calculated cost
|
||||||
// TODO: shouldn't <= below be >=?
|
|
||||||
if ((info.open.contains(np) || info.closed.contains(np)) &&
|
if ((info.open.contains(np) || info.closed.contains(np)) &&
|
||||||
np.g <= newg) {
|
np.g <= newg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove the node from the open list since we're about to
|
||||||
|
// modify its score which determines its placement in the list
|
||||||
|
info.open.remove(np);
|
||||||
|
|
||||||
// update the node's information
|
// update the node's information
|
||||||
np.parent = n;
|
np.parent = n;
|
||||||
np.g = newg;
|
np.g = newg;
|
||||||
@@ -134,7 +139,7 @@ public class AStarPathUtil
|
|||||||
// remove it from the closed list if it's present
|
// remove it from the closed list if it's present
|
||||||
info.closed.remove(np);
|
info.closed.remove(np);
|
||||||
|
|
||||||
// add it to the open list in case it's not already there
|
// add it to the open list for further consideration
|
||||||
info.open.add(np);
|
info.open.add(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +186,7 @@ public class AStarPathUtil
|
|||||||
*/
|
*/
|
||||||
protected static int getDistanceEstimate (int ax, int ay, int bx, int by)
|
protected static int getDistanceEstimate (int ax, int ay, int bx, int by)
|
||||||
{
|
{
|
||||||
return (int)MathUtil.distance(ax, ay, bx, by);
|
return Math.max(Math.abs(bx - ax), Math.abs(by - ay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,14 +269,16 @@ class AStarNode implements Comparable
|
|||||||
{
|
{
|
||||||
int bf = ((AStarNode)o).f;
|
int bf = ((AStarNode)o).f;
|
||||||
|
|
||||||
if (f == bf){
|
// since the set contract is fulfilled using the equality
|
||||||
return 0;
|
// results returned here, and we'd like to allow multiple
|
||||||
}
|
// nodes with equivalent scores in our set, we explicitly
|
||||||
|
// define object equivalence as the result of object.equals(),
|
||||||
|
// else we use the object hashcode since it will return a
|
||||||
|
// consistent, though arbitrary, ordering for the objects.
|
||||||
|
if (f == bf) {
|
||||||
|
return (this == o) ? 0 : (hashCode() - o.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
if (f < bf) {
|
return f - bf;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ViewerSceneViewPanel.java,v 1.10 2001/08/15 02:30:28 shaper Exp $
|
// $Id: ViewerSceneViewPanel.java,v 1.11 2001/08/15 22:06:21 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.miso.viewer;
|
package com.threerings.miso.viewer;
|
||||||
|
|
||||||
@@ -41,6 +41,9 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
|||||||
// load up the initial scene
|
// load up the initial scene
|
||||||
prepareStartingScene();
|
prepareStartingScene();
|
||||||
|
|
||||||
|
_smodel.setShowCoordinates(true);
|
||||||
|
_smodel.setShowSpritePaths(true);
|
||||||
|
|
||||||
PerformanceMonitor.register(this, "paint", 1000);
|
PerformanceMonitor.register(this, "paint", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +95,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
|||||||
|
|
||||||
// get the path from here to there
|
// get the path from here to there
|
||||||
Path path = _view.getPath(_sprite, x, y);
|
Path path = _view.getPath(_sprite, x, y);
|
||||||
if (path != null) {
|
_sprite.move(path);
|
||||||
_sprite.move(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hackily highlight the tile that was clicked on for happy testing
|
// hackily highlight the tile that was clicked on for happy testing
|
||||||
((EditableSceneView)_view).setHighlightedFull(x, y);
|
((EditableSceneView)_view).setHighlightedFull(x, y);
|
||||||
|
|||||||
Reference in New Issue
Block a user