diff --git a/src/java/com/threerings/media/sprite/AnimationManager.java b/src/java/com/threerings/media/sprite/AnimationManager.java index 0e7a4b6b5..50ca82a4d 100644 --- a/src/java/com/threerings/media/sprite/AnimationManager.java +++ b/src/java/com/threerings/media/sprite/AnimationManager.java @@ -1,5 +1,5 @@ // -// $Id: AnimationManager.java,v 1.1 2001/07/28 01:50:07 shaper Exp $ +// $Id: AnimationManager.java,v 1.2 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.sprite; @@ -28,7 +28,11 @@ public class AnimationManager Interval refresher = new Interval() { public void intervalExpired (int id, Object arg) { + // refresh the display _target.repaint(); + + // call tick on all sprites + _spritemgr.tick(); } }; diff --git a/src/java/com/threerings/media/sprite/MobileSprite.java b/src/java/com/threerings/media/sprite/MobileSprite.java index 1b0b1386c..cc89413dd 100644 --- a/src/java/com/threerings/media/sprite/MobileSprite.java +++ b/src/java/com/threerings/media/sprite/MobileSprite.java @@ -1,8 +1,9 @@ // -// $Id: MobileSprite.java,v 1.1 2001/07/30 15:38:52 shaper Exp $ +// $Id: MobileSprite.java,v 1.2 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.sprite; +import com.threerings.miso.Log; import com.threerings.miso.tile.Tile; import com.threerings.miso.tile.TileManager; @@ -58,6 +59,47 @@ public class MobileSprite extends Sprite return tiles; } + /** + * Alter the sprite's direction to reflect the direction the + * destination point lies in before calling the superclass's + * setDestination method. + * + * @param x the destination x-position. + * @param y the destination y-position. + */ + public void setDestination (int x, int y) + { + // update the sprite tiles to reflect the direction + setTiles(_charTiles[_dir = getDirection(x, y)]); + + // call superclass to effect the beginnings of the move + super.setDestination(x, y); + + if (_state == STATE_MOVING) { + setAnimationDelay(0); + } + } + + /** + * Return the directional constant corresponding to the direction + * the specified point is in from the sprite. + */ + protected int getDirection (int x, int y) + { + if (x >= this.x - DIR_BUFFER && x <= this.x + DIR_BUFFER) { + return (y < this.y) ? DIR_NORTH : DIR_SOUTH; + + } else if (y >= this.y - DIR_BUFFER && y <= this.y + DIR_BUFFER) { + return (x >= this.x) ? DIR_EAST : DIR_WEST; + + } else if (x > this.x) { + return (y < this.y) ? DIR_NORTHEAST : DIR_SOUTHEAST; + + } else { + return (y < this.y) ? DIR_NORTHWEST : DIR_SOUTHWEST; + } + } + /** The number of distinct directions the character may face. */ protected static final int NUM_DIRECTIONS = 8; @@ -74,6 +116,12 @@ public class MobileSprite extends Sprite /** The number of frames of animation for each direction. */ protected static final int NUM_DIR_FRAMES = 8; + /** + * The buffer space in pixels allowed for horizontal or vertical + * selection of movement north/south or east/west, respectively. + */ + protected static final int DIR_BUFFER = 20; + /** The animation frames for the sprite facing each direction. */ protected Tile[][] _charTiles; diff --git a/src/java/com/threerings/media/sprite/Sprite.java b/src/java/com/threerings/media/sprite/Sprite.java index 61d24abd1..a2a575f2c 100644 --- a/src/java/com/threerings/media/sprite/Sprite.java +++ b/src/java/com/threerings/media/sprite/Sprite.java @@ -1,11 +1,13 @@ // -// $Id: Sprite.java,v 1.2 2001/07/30 15:38:52 shaper Exp $ +// $Id: Sprite.java,v 1.3 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.sprite; -import java.awt.Graphics2D; +import java.awt.*; +import com.threerings.miso.Log; import com.threerings.miso.tile.Tile; +import com.threerings.miso.util.MathUtil; /** * The Sprite class represents a single moveable object within a @@ -53,8 +55,13 @@ public class Sprite this.x = x; this.y = y; - _tiles = tiles; - _curframe = 0; + _curFrame = 0; + _animDelay = -1; + _numTicks = 0; + setTiles(_tiles); + + _dest = new Point(); + _state = STATE_NONE; } /** @@ -62,10 +69,9 @@ public class Sprite */ public void paint (Graphics2D gfx) { - Tile tile = _tiles[_curframe]; - int xpos = x - (tile.width / 2); - int ypos = y - tile.height; - gfx.drawImage(tile.img, xpos, ypos, null); + int xpos = x - (_curTile.width / 2); + int ypos = y - _curTile.height; + gfx.drawImage(_curTile.img, xpos, ypos, null); } /** @@ -82,8 +88,19 @@ public class Sprite public boolean inside (int x, int y, int width, int height) { // treat the sprite as having a width and height of 1 pixel for now - return (this.x >= x && this.x <= (x + width) && - this.y >= y && this.y <= (y + height)); + return (this.x >= x && this.x < (x + width) && + this.y >= y && this.y < (y + height)); + } + + /** + * Set the number of ticks to wait before switching to the next + * tile in the array of tiles used to display the sprite. + * + * @param ticks the number of ticks. + */ + public void setAnimationDelay (int ticks) + { + _animDelay = ticks; } /** @@ -94,11 +111,101 @@ public class Sprite public void setTiles (Tile[] tiles) { _tiles = tiles; + if (_tiles != null) { + _curTile = _tiles[_curFrame]; + } } + /** + * Set the destination of the sprite in pixel coordinates. + * + * @param x the destination x-position. + * @param y the destination y-position. + */ + public void setDestination (int x, int y) + { + // bail if we're already there + if (x == this.x && y == this.y) return; + + // note our destination + _dest.setLocation(x, y); + + // 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; + + // init position data used to track fractional pixels + _movex = this.x; + _movey = this.y; + + // and that we're moving toward it + _state = STATE_MOVING; + } + + /** + * This method is called periodically by the SpriteManager to give + * the sprite a chance to update its state. + */ + public void tick () + { + // increment the display tile if performing tile animation + if (_animDelay != -1 && (_numTicks++ == _animDelay)) { + _numTicks = 0; + if (++_curFrame > _tiles.length - 1) _curFrame = 0; + _curTile = _tiles[_curFrame]; + } + + 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; + + // and note our stoppage + _animDelay = -1; + _state = STATE_NONE; + } + break; + } + } + + // State constants. + protected static final int STATE_NONE = 0; + protected static final int STATE_MOVING = 1; + /** The tiles used to render the sprite. */ protected Tile[] _tiles; + /** The current tile to render the sprite. */ + protected Tile _curTile; + /** The current tile index to render. */ - protected int _curframe; + protected int _curFrame; + + /** The sprite's destination coordinates. */ + protected Point _dest; + + /** The sprite's current state. */ + protected int _state; + + /** The sprite position with fractional pixels while moving. */ + protected float _movex, _movey; + + /** The distance to move the sprite per tick in fractional pixels. */ + protected float _incx, _incy; + + /** The number of ticks to wait before proceeding to the next tile. */ + protected int _animDelay; + + /** The number of ticks since the last tile animation. */ + protected int _numTicks; } diff --git a/src/java/com/threerings/media/sprite/SpriteManager.java b/src/java/com/threerings/media/sprite/SpriteManager.java index ca4a1c9d0..78b0aeb55 100644 --- a/src/java/com/threerings/media/sprite/SpriteManager.java +++ b/src/java/com/threerings/media/sprite/SpriteManager.java @@ -1,11 +1,13 @@ // -// $Id: SpriteManager.java,v 1.2 2001/07/30 15:38:52 shaper Exp $ +// $Id: SpriteManager.java,v 1.3 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.sprite; import java.awt.Graphics2D; import java.util.ArrayList; +import com.threerings.miso.Log; + /** * The SpriteManager manages the sprites running about in the game. */ @@ -55,6 +57,20 @@ public class SpriteManager } } + /** + * Call Sprite.tick() on all sprite objects to give + * them a chance to move themselves about, change their display + * image, and so forth. + */ + public void tick () + { + int size = _sprites.size(); + for (int ii = 0; ii < size; ii++) { + Sprite sprite = (Sprite)_sprites.get(ii); + sprite.tick(); + } + } + /** The sprite objects we're managing. */ protected ArrayList _sprites; } diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java index cf8f91253..8f3873cf2 100644 --- a/src/java/com/threerings/miso/client/IsoSceneView.java +++ b/src/java/com/threerings/miso/client/IsoSceneView.java @@ -1,5 +1,5 @@ // -// $Id: IsoSceneView.java,v 1.18 2001/07/30 15:38:52 shaper Exp $ +// $Id: IsoSceneView.java,v 1.19 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.scene; @@ -71,7 +71,7 @@ public class IsoSceneView implements EditableSceneView paintHighlightedTile(gfx, _htile.x, _htile.y); // draw lines illustrating tracking of the mouse position - paintMouseLines(gfx); + paintMouseLines(gfx); // restore the original clipping region gfx.setClip(oldclip); diff --git a/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java index 3654d14fa..a6cc00e5b 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.3 2001/07/30 15:38:52 shaper Exp $ +// $Id: SceneViewPanel.java,v 1.4 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.viewer; @@ -13,7 +13,7 @@ import com.threerings.miso.Log; import com.threerings.miso.viewer.util.ViewerContext; import com.threerings.miso.scene.*; import com.threerings.miso.scene.xml.XMLFileSceneRepository; -import com.threerings.miso.sprite.SpriteManager; +import com.threerings.miso.sprite.*; /** * The SceneViewPanel class is responsible for managing a SceneView, @@ -25,10 +25,13 @@ public class SceneViewPanel extends JPanel /** * Construct the panel and initialize it with a context. */ - public SceneViewPanel (ViewerContext ctx, SpriteManager spritemgr) + public SceneViewPanel (ViewerContext ctx, SpriteManager spritemgr, + Sprite sprite) { _ctx = ctx; + _sprite = sprite; + // construct the view object _view = new IsoSceneView(_ctx.getTileManager(), spritemgr); @@ -77,7 +80,6 @@ public class SceneViewPanel extends JPanel { super.paint(g); _view.paint(g); - Log.info("paint()"); } /** MouseListener interface methods */ @@ -93,7 +95,10 @@ public class SceneViewPanel extends JPanel public void mousePressed (MouseEvent e) { - Log.info("mousePressed [x=" + e.getX() + ", y=" + e.getY() + "]."); + int x = e.getX(), y = e.getY(); + Log.info("mousePressed [x=" + x + ", y=" + y + "]."); + _sprite.setDestination(x, y); + ((EditableSceneView)_view).setHighlightedTile(x, y); } public void mouseReleased (MouseEvent e) { } @@ -114,6 +119,8 @@ public class SceneViewPanel extends JPanel /** The default scene to load and display. */ protected static final String DEF_SCENE = "rsrc/scenes/default.xml"; + protected Sprite _sprite; + /** The context object. */ protected ViewerContext _ctx; diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java index 4fc1f6712..f3fdf2820 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java @@ -1,5 +1,5 @@ // -// $Id: ViewerFrame.java,v 1.3 2001/07/30 15:38:52 shaper Exp $ +// $Id: ViewerFrame.java,v 1.4 2001/07/31 01:38:28 shaper Exp $ package com.threerings.miso.viewer; @@ -40,13 +40,14 @@ class ViewerFrame extends JFrame implements WindowListener SpriteManager spritemgr = new SpriteManager(); TileManager tilemgr = _ctx.getTileManager(); - // set up the scene view panel with a default scene - SceneViewPanel svpanel = new SceneViewPanel(_ctx, spritemgr); - // add the test character sprite to the sprite manager MobileSprite ms = new MobileSprite(300, 300, tilemgr, TSID_CHAR); + //ms.setAnimationDelay(10); spritemgr.addSprite(ms); + // set up the scene view panel with a default scene + SceneViewPanel svpanel = new SceneViewPanel(_ctx, spritemgr, ms); + // create the animation manager for this panel AnimationManager animmgr = new AnimationManager(spritemgr, svpanel);