Create and have the sprite follow a path rather than explicitly
setting the sprite destination. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@152 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 <code>java.awt.Rectangle</code> 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);
|
||||
}
|
||||
|
||||
@@ -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 <code>SceneViewPanel</code> class is responsible for managing a
|
||||
* <code>SceneView</code>, 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. */
|
||||
|
||||
Reference in New Issue
Block a user