From 1032b8f3259ed4b2d770fee4244d21ba5557489c Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Thu, 2 Aug 2001 00:42:02 +0000 Subject: [PATCH] Moved much of the IsoSceneView data into the IsoSceneModel. More work on sprites and animation. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@138 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../media/sprite/AnimationManager.java | 55 ++-- .../threerings/media/sprite/MobileSprite.java | 38 +-- .../com/threerings/media/sprite/Sprite.java | 66 ++++- .../media/sprite/SpriteManager.java | 55 +++- .../media/util/LineSegmentPath.java | 93 +++++++ .../com/threerings/media/util/PathNode.java | 31 +++ .../media/util/PerformanceMonitor.java | 163 ++++++++++++ .../media/util/PerformanceObserver.java | 22 ++ .../threerings/miso/client/IsoSceneView.java | 240 ++++++++++-------- .../miso/client/IsoSceneViewModel.java | 146 +++++++++++ .../com/threerings/miso/client/SceneView.java | 15 +- .../miso/viewer/SceneViewPanel.java | 35 ++- .../com/threerings/miso/viewer/ViewerApp.java | 4 +- .../threerings/miso/viewer/ViewerFrame.java | 9 +- 14 files changed, 795 insertions(+), 177 deletions(-) create mode 100644 src/java/com/threerings/media/util/LineSegmentPath.java create mode 100644 src/java/com/threerings/media/util/PathNode.java create mode 100644 src/java/com/threerings/media/util/PerformanceMonitor.java create mode 100644 src/java/com/threerings/media/util/PerformanceObserver.java create mode 100644 src/java/com/threerings/miso/client/IsoSceneViewModel.java diff --git a/src/java/com/threerings/media/sprite/AnimationManager.java b/src/java/com/threerings/media/sprite/AnimationManager.java index 50ca82a4d..6ed1b7960 100644 --- a/src/java/com/threerings/media/sprite/AnimationManager.java +++ b/src/java/com/threerings/media/sprite/AnimationManager.java @@ -1,47 +1,67 @@ // -// $Id: AnimationManager.java,v 1.2 2001/07/31 01:38:28 shaper Exp $ +// $Id: AnimationManager.java,v 1.3 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.sprite; import java.awt.Component; +import java.util.ArrayList; import com.samskivert.util.Interval; import com.samskivert.util.IntervalManager; +import com.threerings.miso.Log; +import com.threerings.miso.scene.SceneView; +import com.threerings.miso.util.PerformanceMonitor; +import com.threerings.miso.util.PerformanceObserver; /** * The AnimationManager handles the regular refreshing of the scene * view to allow for animation. It also may someday manage special * scene-wide animations, such as rain, fog, or earthquakes. */ -public class AnimationManager +public class AnimationManager implements Interval, PerformanceObserver { /** * Construct and initialize the animation manager with a sprite * manager and the panel that animations will take place within. */ - public AnimationManager (SpriteManager spritemgr, Component target) + public AnimationManager (SpriteManager spritemgr, Component target, + SceneView view) { + // save off references to the objects we care about _spritemgr = spritemgr; _target = target; + _view = view; - // create the interval for refreshing the display - Interval refresher = new Interval() { - public void intervalExpired (int id, Object arg) - { - // refresh the display - _target.repaint(); + // register to monitor the refresh action + PerformanceMonitor.register(this, "refresh", 1000); - // call tick on all sprites - _spritemgr.tick(); - } - }; + // register ourselves with the interval manager + IntervalManager.register(this, REFRESH_INTERVAL, null, true); + } - // register ourselves with the interval mgr - IntervalManager.register(refresher, REFRESH_INTERVAL, null, true); + public void intervalExpired (int id, Object arg) + { + // refresh the display + _target.repaint(); + + // call tick on all sprites + _spritemgr.tick(); + + // invalidate screen-rects dirtied by sprites + ArrayList rects = _spritemgr.getDirtyRects(); + _view.invalidateRects(rects); + + // update frame-rate information + //PerformanceMonitor.tick(this, "refresh"); + } + + public void checkpoint (String name, int ticks) + { + Log.info(name + "[ticks=" + ticks + "]."); } /** The desired number of refresh operations per second. */ - protected static final int FRAME_RATE = 60; + protected static final int FRAME_RATE = 20; /** The milliseconds to sleep to obtain desired frame rate. */ protected static final long REFRESH_INTERVAL = 1000 / FRAME_RATE; @@ -51,4 +71,7 @@ public class AnimationManager /** The component to refresh. */ protected Component _target; + + /** The scene view. */ + protected SceneView _view; } diff --git a/src/java/com/threerings/media/sprite/MobileSprite.java b/src/java/com/threerings/media/sprite/MobileSprite.java index cc89413dd..90a164b36 100644 --- a/src/java/com/threerings/media/sprite/MobileSprite.java +++ b/src/java/com/threerings/media/sprite/MobileSprite.java @@ -1,5 +1,5 @@ // -// $Id: MobileSprite.java,v 1.2 2001/07/31 01:38:28 shaper Exp $ +// $Id: MobileSprite.java,v 1.3 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.sprite; @@ -24,11 +24,14 @@ public class MobileSprite extends Sprite * @param tilemgr the tile manager to retrieve tiles from. * @param tsid the tileset id containing the sprite tiles. */ - public MobileSprite (int x, int y, TileManager tilemgr, int tsid) + public MobileSprite (SpriteManager spritemgr, int x, int y, + TileManager tilemgr, int tsid) { - super(x, y); + super(spritemgr, x, y); + _charTiles = getTiles(tilemgr, tsid); - _dir = DIR_SOUTH; + _dir = Path.DIR_SOUTH; + setTiles(_charTiles[0]); } @@ -36,7 +39,7 @@ public class MobileSprite extends Sprite * Returns a two-dimensional array of tiles corresponding to the * frames of animation used to render the mobile sprite in each of * the directions it may face. The tileset id referenced must - * contain NUM_DIRECTIONS rows of tiles, with each + * contain Path.NUM_DIRECTIONS rows of tiles, with each * row containing NUM_DIR_FRAMES tiles. * * @param tilemgr the tile manager to retrieve tiles from. @@ -47,9 +50,9 @@ public class MobileSprite extends Sprite protected Tile[][] getTiles (TileManager tilemgr, int tsid) { Tile[][] tiles = - new Tile[NUM_DIRECTIONS][NUM_DIR_FRAMES]; + new Tile[Path.NUM_DIRECTIONS][NUM_DIR_FRAMES]; - for (int ii = 0; ii < NUM_DIRECTIONS; ii++) { + for (int ii = 0; ii < Path.NUM_DIRECTIONS; ii++) { for (int jj = 0; jj < NUM_DIR_FRAMES; jj++) { int idx = (ii * NUM_DIR_FRAMES) + jj; tiles[ii][jj] = tilemgr.getTile(tsid, idx); @@ -87,32 +90,19 @@ public class MobileSprite extends 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; + return (y < this.y) ? Path.DIR_NORTH : Path.DIR_SOUTH; } else if (y >= this.y - DIR_BUFFER && y <= this.y + DIR_BUFFER) { - return (x >= this.x) ? DIR_EAST : DIR_WEST; + return (x >= this.x) ? Path.DIR_EAST : Path.DIR_WEST; } else if (x > this.x) { - return (y < this.y) ? DIR_NORTHEAST : DIR_SOUTHEAST; + return (y < this.y) ? Path.DIR_NORTHEAST : Path.DIR_SOUTHEAST; } else { - return (y < this.y) ? DIR_NORTHWEST : DIR_SOUTHWEST; + return (y < this.y) ? Path.DIR_NORTHWEST : Path.DIR_SOUTHWEST; } } - /** The number of distinct directions the character may face. */ - protected static final int NUM_DIRECTIONS = 8; - - // Direction constants - protected static final int DIR_SOUTH = 0; - protected static final int DIR_SOUTHWEST = 1; - protected static final int DIR_WEST = 2; - protected static final int DIR_NORTHWEST = 3; - protected static final int DIR_NORTH = 4; - protected static final int DIR_NORTHEAST = 5; - protected static final int DIR_EAST = 6; - protected static final int DIR_SOUTHEAST = 7; - /** The number of frames of animation for each direction. */ protected static final int NUM_DIR_FRAMES = 8; diff --git a/src/java/com/threerings/media/sprite/Sprite.java b/src/java/com/threerings/media/sprite/Sprite.java index a2a575f2c..491b1abe2 100644 --- a/src/java/com/threerings/media/sprite/Sprite.java +++ b/src/java/com/threerings/media/sprite/Sprite.java @@ -1,5 +1,5 @@ // -// $Id: Sprite.java,v 1.3 2001/07/31 01:38:28 shaper Exp $ +// $Id: Sprite.java,v 1.4 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.sprite; @@ -25,13 +25,14 @@ public class Sprite /** * Construct a Sprite object. * + * @param spritemgr the sprite manager. * @param x the sprite x-position in pixels. * @param y the sprite y-position in pixels. * @param tiles the tiles used to display the sprite. */ - public Sprite (int x, int y, Tile[] tiles) + public Sprite (SpriteManager spritemgr, int x, int y, Tile[] tiles) { - init(x, y, tiles); + init(spritemgr, x, y, tiles); } /** @@ -39,29 +40,35 @@ public class Sprite * sprite should be populated with a set of tiles used to display * it via a subsequent call to setTiles(). * + * @param spritemgr the sprite manager. * @param x the sprite x-position in pixels. * @param y the sprite y-position in pixels. */ - public Sprite (int x, int y) + public Sprite (SpriteManager spritemgr, int x, int y) { - init(x, y, null); + init(spritemgr, x, y, null); } /** - * Initialize the sprite object with the specified parameters. + * Initialize the sprite object with its variegated parameters. */ - protected void init (int x, int y, Tile[] tiles) + protected void init (SpriteManager spritemgr, int x, int y, Tile[] tiles) { + _spritemgr = spritemgr; + this.x = x; this.y = y; _curFrame = 0; _animDelay = -1; _numTicks = 0; + setTiles(_tiles); _dest = new Point(); _state = STATE_NONE; + + invalidate(); } /** @@ -72,6 +79,7 @@ public class Sprite int xpos = x - (_curTile.width / 2); int ypos = y - _curTile.height; gfx.drawImage(_curTile.img, xpos, ypos, null); +// Log.info("Sprite painting image [x=" + xpos + ", y=" + ypos + "]."); } /** @@ -87,9 +95,22 @@ 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 + // note that we consider the current tile for sprite + // width/height, and since the tile may change we're at the + // mercy of the tile creators to make sure all tiles for a + // given sprite are the same width. + + // we might want to check this when tiles are set for the + // sprite, or require that the sprite width/height be + // specified separately when the sprite is created. or + // perhaps we'd like to be able to have sprites with variable + // width? i can't think why. + return (this.x >= x && this.x < (x + width) && this.y >= y && this.y < (y + height)); + +// return (this.x >= x && this.x + _curTile.width < (x + width) && +// this.y >= y && this.y + _curTile.height < (y + height)); } /** @@ -113,6 +134,7 @@ public class Sprite _tiles = tiles; if (_tiles != null) { _curTile = _tiles[_curFrame]; + invalidate(); } } @@ -143,6 +165,25 @@ public class Sprite _state = STATE_MOVING; } + /** + * Invalidate the sprite's display rectangle for later repainting. + */ + public void invalidate () + { + if (_curTile == null) return; + + int xpos = x - (_curTile.width / 2); + int ypos = y - _curTile.height; + + Rectangle dirty = + new Rectangle(xpos, ypos, _curTile.width, _curTile.height); + +// Log.info("Sprite dirtying rect [x=" + dirty.x + ", y=" + dirty.y + +// ", width=" + dirty.width + ", height=" + dirty.height + "]."); + + _spritemgr.addDirtyRect(dirty); + } + /** * This method is called periodically by the SpriteManager to give * the sprite a chance to update its state. @@ -154,6 +195,7 @@ public class Sprite _numTicks = 0; if (++_curFrame > _tiles.length - 1) _curFrame = 0; _curTile = _tiles[_curFrame]; + invalidate(); } switch (_state) { @@ -170,6 +212,9 @@ public class Sprite x = _dest.x; y = _dest.y; + // invalidate the sprite in its new location + invalidate(); + // and note our stoppage _animDelay = -1; _state = STATE_NONE; @@ -178,7 +223,7 @@ public class Sprite } } - // State constants. + /** State constants. */ protected static final int STATE_NONE = 0; protected static final int STATE_MOVING = 1; @@ -208,4 +253,7 @@ public class Sprite /** The number of ticks since the last tile animation. */ protected int _numTicks; + + /** The sprite manager. */ + protected SpriteManager _spritemgr; } diff --git a/src/java/com/threerings/media/sprite/SpriteManager.java b/src/java/com/threerings/media/sprite/SpriteManager.java index 78b0aeb55..87e8f7a49 100644 --- a/src/java/com/threerings/media/sprite/SpriteManager.java +++ b/src/java/com/threerings/media/sprite/SpriteManager.java @@ -1,9 +1,10 @@ // -// $Id: SpriteManager.java,v 1.3 2001/07/31 01:38:28 shaper Exp $ +// $Id: SpriteManager.java,v 1.4 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.sprite; import java.awt.Graphics2D; +import java.awt.Rectangle; import java.util.ArrayList; import com.threerings.miso.Log; @@ -19,6 +20,17 @@ public class SpriteManager public SpriteManager () { _sprites = new ArrayList(); + _dirty = new ArrayList(); + } + + /** + * Add a rectangle to the dirty rectangle list. + * + * @param rect the rectangle to add. + */ + public void addDirtyRect (Rectangle rect) + { + _dirty.add(rect); } /** @@ -31,6 +43,38 @@ public class SpriteManager _sprites.add(sprite); } + /** + * Return the list of dirty rects in screen pixel coordinates that + * have been created by any sprites since the last time the dirty + * rects were requested. + * + * @return the list of dirty rects. + */ + public ArrayList getDirtyRects () + { + // create a copy of the dirty rectangles + ArrayList dirty = (ArrayList)_dirty.clone(); + + // clear out the list + _dirty.clear(); + + // return the full original list + 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 specified pixel bounds * to the given graphics context. @@ -58,9 +102,9 @@ 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. + * Call tick() on all sprite objects to give them a + * chance to move themselves about, change their display image, + * and so forth. */ public void tick () { @@ -73,4 +117,7 @@ public class SpriteManager /** The sprite objects we're managing. */ protected ArrayList _sprites; + + /** The dirty rectangles created by sprites. */ + protected ArrayList _dirty; } diff --git a/src/java/com/threerings/media/util/LineSegmentPath.java b/src/java/com/threerings/media/util/LineSegmentPath.java new file mode 100644 index 000000000..60e07c689 --- /dev/null +++ b/src/java/com/threerings/media/util/LineSegmentPath.java @@ -0,0 +1,93 @@ +// +// $Id: LineSegmentPath.java,v 1.1 2001/08/02 00:42:02 shaper Exp $ + +package com.threerings.miso.sprite; + +import java.util.ArrayList; +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. + */ +public class Path +{ + /** The number of distinct directions. */ + public static final int NUM_DIRECTIONS = 8; + + /** Direction constants. */ + public static final int DIR_SOUTH = 0; + public static final int DIR_SOUTHWEST = 1; + public static final int DIR_WEST = 2; + public static final int DIR_NORTHWEST = 3; + public static final int DIR_NORTH = 4; + public static final int DIR_NORTHEAST = 5; + public static final int DIR_EAST = 6; + public static final int DIR_SOUTHEAST = 7; + + /** + * Construct a Path object. + */ + public Path () + { + _nodes = new ArrayList(); + } + + /** + * Add a node to the path with the specified destination point and + * facing direction. + * + * @param x the x-position. + * @param y the y-position. + * @param dir the facing direction. + */ + public void addNode (int x, int y, int dir) + { + _nodes.add(new PathNode(x, y, dir)); + } + + /** + * Return an enumeration of the PathNode objects in this path. + */ + public Enumeration elements () + { + return new Enumerator(_nodes); + } + + /** + * Return the number of nodes in the path. + */ + public int size () + { + return _nodes.size(); + } + + /** + * Internal class that provides enumeration functionality for the path. + */ + class Enumerator implements Enumeration + { + public Enumerator (ArrayList nodes) + { + _nodes = nodes; + _idx = 0; + } + + public boolean hasMoreElements() + { + return (_idx < _nodes.size()); + } + + public Object nextElement () + { + return _nodes.get(_idx++); + } + + protected ArrayList _nodes; + protected int _idx; + } + + /** The nodes that make up the path. */ + protected ArrayList _nodes; +} diff --git a/src/java/com/threerings/media/util/PathNode.java b/src/java/com/threerings/media/util/PathNode.java new file mode 100644 index 000000000..65b6cb1f4 --- /dev/null +++ b/src/java/com/threerings/media/util/PathNode.java @@ -0,0 +1,31 @@ +// +// $Id: PathNode.java,v 1.1 2001/08/02 00:42:02 shaper Exp $ + +package com.threerings.miso.sprite; + +import java.awt.Point; + +/** + * The PathNode object is a single destination point in a Path. + */ +public class PathNode +{ + /** The node coordinates in screen pixels. */ + public Point loc; + + /** The direction to face while heading toward the node. */ + public int dir; + + /** + * Construct a PathNode object. + * + * @param x the node x-position. + * @param y the node y-position. + * @param dir the facing direction. + */ + public PathNode (int x, int y, int dir) + { + loc = new Point(x, y); + this.dir = dir; + } +} diff --git a/src/java/com/threerings/media/util/PerformanceMonitor.java b/src/java/com/threerings/media/util/PerformanceMonitor.java new file mode 100644 index 000000000..78c9db6a4 --- /dev/null +++ b/src/java/com/threerings/media/util/PerformanceMonitor.java @@ -0,0 +1,163 @@ +// +// $Id: PerformanceMonitor.java,v 1.1 2001/08/02 00:42:02 shaper Exp $ + +package com.threerings.miso.util; + +import java.util.HashMap; + +import com.threerings.miso.Log; + +/** + * The PerformanceMonitor class provides a simple + * mechanism for monitoring the number of times an action takes place + * within a certain time period. + * + *

The action being tracked should be registered with a suitable + * name via register(), and tick() should be + * called each time the action is performed. + * + *

Whenever tick() is called and the checkpoint time + * interval has elapsed since the last checkpoint (if any), the + * observer will be notified to that effect by a call to + * PerformanceObserver.checkpoint(). + * + *

Note that this is not intended to be used as an + * industrial-strength profiling or performance monitoring tool. The + * checkpoint time interval granularity is in milliseconds, not + * microseconds; and the observer's checkpoint() method + * will never be called until/unless a subsequent call to + * tick() is made after the requested number of + * milliseconds have passed since the last checkpoint. + */ +public class PerformanceMonitor +{ + /** + * Register a new action with an observer, the action name, and + * the milliseconds to wait between checkpointing the action's + * performance. + * + * @param obs the action observer. + * @param name the action name. + * @param delta the milliseconds between checkpoints. + */ + public static void register (PerformanceObserver obs, String name, + long delta) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + // create it if it didn't exist + _observers.put(obs, actions = new HashMap()); + } + + // add the action to the set we're tracking + actions.put(name, new PerformanceAction(obs, name, delta)); + } + + /** + * Un-register the named action associated with the given observer. + * + * @param obs the action observer. + * @param name the action name. + */ + public static void unregister (PerformanceObserver obs, String name) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + Log.warning("Attempt to unregister by unknown observer " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // attempt to remove the specified action + PerformanceAction action = (PerformanceAction)actions.remove(name); + if (action == null) { + Log.warning("Attempt to unregister unknown action " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // if the observer has no actions left, remove the observer's action + // hash in its entirety + if (actions.size() == 0) { + _observers.remove(obs); + } + } + + /** + * Tick the named action associated with the given observer. + * + * @param obs the action observer. + * @param name the action name. + */ + public static void tick (PerformanceObserver obs, String name) + { + // get the observer's action hashtable + HashMap actions = (HashMap)_observers.get(obs); + if (actions == null) { + Log.warning("Attempt to tick by unknown observer " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // get the specified action + PerformanceAction action = (PerformanceAction)actions.get(name); + if (action == null) { + Log.warning("Attempt to tick unknown value " + + "[observer=" + obs + ", name=" + name + "]."); + return; + } + + // tick the action + action.tick(); + } + + /** The observers monitoring some set of actions. */ + protected static HashMap _observers = new HashMap(); +} + +class PerformanceAction +{ + public PerformanceAction (PerformanceObserver obs, String name, long delta) + { + _obs = obs; + _name = name; + _delta = delta; + _lastDelta = System.currentTimeMillis(); + } + + public void tick () + { + _numTicks++; + + long now = System.currentTimeMillis(); + if ((now - _lastDelta) >= _delta) { + // update the last checkpoint time + _lastDelta = now; + + // notify our observer of the checkpoint + _obs.checkpoint(_name, _numTicks); + + // reset the tick count + _numTicks = 0; + } + } + + public String toString () + { + StringBuffer buf = new StringBuffer(); + buf.append("[obs=").append(_obs); + buf.append(", name=").append(_name); + buf.append(", delta=").append(_delta); + buf.append(", lastDelta=").append(_lastDelta); + buf.append(", numTicks=").append(_numTicks); + return buf.append("]").toString(); + } + + protected PerformanceObserver _obs; + protected String _name; + protected long _delta; + protected long _lastDelta; + protected int _numTicks; +} diff --git a/src/java/com/threerings/media/util/PerformanceObserver.java b/src/java/com/threerings/media/util/PerformanceObserver.java new file mode 100644 index 000000000..5fb886303 --- /dev/null +++ b/src/java/com/threerings/media/util/PerformanceObserver.java @@ -0,0 +1,22 @@ +// +// $Id: PerformanceObserver.java,v 1.1 2001/08/02 00:42:02 shaper Exp $ + +package com.threerings.miso.util; + +/** + * The PerformanceObserver interface should be + * implemented by classes that wish to register actions to be + * monitored by the PerformanceMonitor class. + */ +public interface PerformanceObserver +{ + /** + * This method is called by the PerformanceMonitor + * class whenever an action's requested time interval between + * checkpoints has expired. + * + * @param name the action name. + * @param ticks the ticks since the last checkpoint. + */ + public void checkpoint (String name, int ticks); +} diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java index 8f3873cf2..6cc880953 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.19 2001/07/31 01:38:28 shaper Exp $ +// $Id: IsoSceneView.java,v 1.20 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.scene; @@ -11,6 +11,7 @@ import com.threerings.miso.util.MathUtil; import java.awt.*; import java.awt.image.*; +import java.util.ArrayList; /** * The IsoSceneView provides an isometric graphics view of a @@ -24,29 +25,22 @@ public class IsoSceneView implements EditableSceneView * * @param tilemgr the tile manager. */ - public IsoSceneView (TileManager tilemgr, SpriteManager spritemgr) + public IsoSceneView (TileManager tilemgr, SpriteManager spritemgr, + IsoSceneModel model) { _tilemgr = tilemgr; _spritemgr = spritemgr; - _bounds = new Dimension(DEF_BOUNDS_WIDTH, DEF_BOUNDS_HEIGHT); + setModel(model); - _htile = new Point(); - _htile.x = _htile.y = -1; + // initialize the highlighted tile + _htile = new Point(-1, -1); + // get the font used to render tile coordinates _font = new Font("Arial", Font.PLAIN, 7); - _lineX = new Point[2]; - _lineY = new Point[2]; - for (int ii = 0; ii < 2; ii++) { - _lineX[ii] = new Point(); - _lineY[ii] = new Point(); - } - - // pre-calculate the unchanging X-axis line - calculateXAxis(); - - _showCoords = false; + // create the list of dirty rectangles + _dirty = new ArrayList(); } /** @@ -62,21 +56,55 @@ public class IsoSceneView implements EditableSceneView // clip the drawing region to our desired bounds since we // currently draw tiles willy-nilly in undesirable areas. Shape oldclip = gfx.getClip(); - gfx.setClip(0, 0, _bounds.width, _bounds.height); + gfx.setClip(0, 0, _model.bounds.width, _model.bounds.height); // draw the full scene into the offscreen image buffer - renderScene(gfx); + //renderSceneInvalid(gfx); + renderScene(gfx); // draw an outline around the highlighted tile 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); } + /** + * Render the scene to the given graphics context. + * + * @param gfx the graphics context. + */ + protected void renderSceneInvalid (Graphics2D gfx) + { + Point spos = new Point(); + + Log.info("renderSceneInvalid."); + + int size = _dirty.size(); + for (int ii = 0; ii < size; ii++) { + int[] dinfo = (int[])_dirty.remove(0); + + tileToScreen(dinfo[0], dinfo[1], spos); + + Log.info("renderSceneInvalid [tx=" + dinfo[0] + + ", ty=" + dinfo[1] + ", x=" + spos.x + + ", y=" + spos.y + "]."); + + Tile tile = _scene.tiles[dinfo[0]][dinfo[1]][0]; + if (tile == null) continue; + + int ypos = spos.y - (tile.height - _model.tilehei); + gfx.drawImage(tile.img, spos.x, ypos, null); + + // draw all sprites residing in the current tile + _spritemgr.renderSprites( + gfx, spos.x, spos.y, _model.tilewid, _model.tilehei); + } + } + /** * Render the scene to the given graphics context. * @@ -87,9 +115,9 @@ public class IsoSceneView implements EditableSceneView int mx = 1; int my = 0; - int screenY = DEF_CENTER_Y; + int screenY = _model.origin.y; - for (int ii = 0; ii < TILE_RENDER_ROWS; ii++) { + for (int ii = 0; ii < _model.tilerows; ii++) { // determine starting tile coordinates int tx = (ii < Scene.TILE_HEIGHT) ? 0 : mx++; int ty = my; @@ -98,7 +126,7 @@ public class IsoSceneView implements EditableSceneView int length = (ty - tx) + 1; // determine starting screen x-position - int screenX = DEF_CENTER_X - ((length) * ISO_TILE_HALFWIDTH); + int screenX = _model.origin.x - ((length) * _model.tilehwid); for (int jj = 0; jj < length; jj++) { @@ -109,7 +137,7 @@ public class IsoSceneView implements EditableSceneView // determine screen y-position, accounting for // tile image height - int ypos = screenY - (tile.height - ISO_TILE_HEIGHT); + int ypos = screenY - (tile.height - _model.tilehei); // draw the tile image at the appropriate screen position gfx.drawImage(tile.img, screenX, ypos, null); @@ -117,14 +145,16 @@ public class IsoSceneView implements EditableSceneView // draw all sprites residing in the current line of tiles _spritemgr.renderSprites( - gfx, screenX, screenY, (length * ISO_TILE_WIDTH), - ISO_TILE_HEIGHT); + gfx, screenX, screenY, (length * _model.tilewid), + _model.tilehei); // draw tile coordinates in each tile - if (_showCoords) paintCoords(gfx, tx, ty, screenX, screenY); + if (_model.showCoords) { + paintCoords(gfx, tx, ty, screenX, screenY); + } // each tile is one tile-width to the right of the previous - screenX += ISO_TILE_WIDTH; + screenX += _model.tilewid; // advance tile x and decrement tile y as we move to // the right drawing the row @@ -133,7 +163,7 @@ public class IsoSceneView implements EditableSceneView } // each row is a half-tile-height away from the previous row - screenY += ISO_TILE_HALFHEIGHT; + screenY += _model.tilehhei; // advance starting y-axis coordinate unless we've hit bottom if ((++my) > Scene.TILE_HEIGHT - 1) my = Scene.TILE_HEIGHT - 1; @@ -148,19 +178,21 @@ public class IsoSceneView implements EditableSceneView */ protected void paintMouseLines (Graphics2D gfx) { + Point[] lx = _model.lineX, ly = _model.lineY; + // draw the baseline x-axis line gfx.setColor(Color.red); - gfx.drawLine(_lineX[0].x, _lineX[0].y, _lineX[1].x, _lineX[1].y); + gfx.drawLine(lx[0].x, lx[0].y, lx[1].x, lx[1].y); // draw line from last mouse pos to baseline gfx.setColor(Color.yellow); - gfx.drawLine(_lineY[0].x, _lineY[0].y, _lineY[1].x, _lineY[1].y); + gfx.drawLine(ly[0].x, ly[0].y, ly[1].x, ly[1].y); // draw the most recent mouse cursor position gfx.setColor(Color.green); - gfx.fillRect(_lineY[0].x, _lineY[0].y, 2, 2); + gfx.fillRect(ly[0].x, ly[0].y, 2, 2); gfx.setColor(Color.red); - gfx.drawRect(_lineY[0].x - 1, _lineY[0].y - 1, 3, 3); + gfx.drawRect(ly[0].x - 1, ly[0].y - 1, 3, 3); } /** @@ -177,10 +209,10 @@ public class IsoSceneView implements EditableSceneView { gfx.setFont(_font); gfx.setColor(Color.white); - 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); + gfx.drawString("" + x, sx + _model.tilehwid - 2, + sy + _model.tilehhei - 2); + gfx.drawString("" + y, sx + _model.tilehwid - 2, + sy + _model.tilehei - 2); } /** @@ -202,14 +234,14 @@ public class IsoSceneView implements EditableSceneView gfx.setColor(HLT_COLOR); // draw the tile outline - 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); + gfx.drawLine(spos.x, spos.y + _model.tilehhei, + spos.x + _model.tilehwid, spos.y); + gfx.drawLine(spos.x + _model.tilehwid, spos.y, + spos.x + _model.tilewid, spos.y + _model.tilehhei); + gfx.drawLine(spos.x + _model.tilewid, spos.y + _model.tilehhei, + spos.x + _model.tilehwid, spos.y + _model.tilehei); + gfx.drawLine(spos.x + _model.tilehwid, spos.y + _model.tilehei, + spos.x, spos.y + _model.tilehhei); // restore the original stroke gfx.setStroke(ostroke); @@ -228,20 +260,39 @@ public class IsoSceneView implements EditableSceneView } /** - * Pre-calculate the x-axis line (from tile origin to right end of - * x-axis) for later use in converting tile and screen - * coordinates. + * Invalidate a list of rectangles in the view for later repainting. + * + * @param rects the list of Rectangle objects. */ - protected void calculateXAxis () + public void invalidateRects (ArrayList rects) { - // determine the starting point - _lineX[0].x = DEF_CENTER_X; - _bX = (int)-(SLOPE_X * _lineX[0].x); - _lineX[0].y = DEF_CENTER_Y; + int size = rects.size(); + for (int ii = 0; ii < size; ii++) { + Rectangle r = (Rectangle)rects.get(ii); + invalidateScreenRect(r.x, r.y, r.width, r.height); + } + } - // determine the ending point - _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); + /** + * Invalidate the specified rectangle in screen pixel coordinates + * in the view. + * + * @param x the rectangle x-position. + * @param y the rectangle y-position. + * @param width the rectangle width. + * @param height the rectangle height. + */ + public void invalidateScreenRect (int x, int y, int width, int height) + { + Point tpos = new Point(); + screenToTile(x, y, tpos); + +// Log.info("invalidateScreenRect: mapped rect to tile " + +// "[tx=" + tpos.x + ", ty=" + tpos.y + +// ", x=" + x + ", y=" + y + ", width=" + width + +// ", height=" + height + "]."); + + _dirty.add(new int[] { tpos.x, tpos.y }); } /** @@ -255,24 +306,26 @@ public class IsoSceneView implements EditableSceneView */ protected void screenToTile (int sx, int sy, Point tpos) { + Point[] lx = _model.lineX, ly = _model.lineY; + // calculate line parallel to the y-axis (from mouse pos to x-axis) - _lineY[0].x = sx; - _lineY[0].y = sy; - int bY = (int)(sy - (SLOPE_Y * sx)); + ly[0].setLocation(sx, sy); + int bY = (int)(sy - (_model.SLOPE_Y * sx)); // determine intersection of x- and y-axis lines - _lineY[1].x = (int)((bY - (_bX + DEF_CENTER_Y)) / (SLOPE_X - SLOPE_Y)); - _lineY[1].y = (int)((SLOPE_Y * _lineY[1].x) + bY); + ly[1].x = (int)((bY - (_model.bX + _model.origin.y)) / + (_model.SLOPE_X - _model.SLOPE_Y)); + ly[1].y = (int)((_model.SLOPE_Y * ly[1].x) + bY); // determine distance of mouse pos along the x axis int xdist = (int) MathUtil.distance( - _lineX[0].x, _lineX[0].y, _lineY[1].x, _lineY[1].y); - tpos.x = (int)(xdist / TILE_EDGE_LENGTH); + lx[0].x, lx[0].y, ly[1].x, ly[1].y); + tpos.x = (int)(xdist / _model.tilelen); // determine distance of mouse pos along the y-axis int ydist = (int) MathUtil.distance( - _lineY[0].x, _lineY[0].y, _lineY[1].x, _lineY[1].y); - tpos.y = (int)(ydist / TILE_EDGE_LENGTH); + ly[0].x, ly[0].y, ly[1].x, ly[1].y); + tpos.y = (int)(ydist / _model.tilelen); } /** @@ -286,8 +339,8 @@ public class IsoSceneView implements EditableSceneView */ protected void tileToScreen (int x, int y, Point spos) { - spos.x = _lineX[0].x + ((x - y - 1) * ISO_TILE_HALFWIDTH); - spos.y = _lineX[0].y + ((x + y) * ISO_TILE_HALFHEIGHT); + spos.x = _model.lineX[0].x + ((x - y - 1) * _model.tilehwid); + spos.y = _model.lineX[0].y + ((x + y) * _model.tilehhei); } public void setScene (Scene scene) @@ -297,7 +350,7 @@ public class IsoSceneView implements EditableSceneView public void setShowCoordinates (boolean show) { - _showCoords = show; + _model.showCoords = show; } public void setTile (int x, int y, int lnum, Tile tile) @@ -307,32 +360,11 @@ 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 * ISO_TILE_WIDTH; - - /** The default height of a scene in pixels. */ - 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 = - (Scene.TILE_WIDTH * Scene.TILE_HEIGHT) - 1; - - /** The starting x-position to render the view. */ - 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 * 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((ISO_TILE_HALFWIDTH * ISO_TILE_HALFWIDTH) + - (ISO_TILE_HALFHEIGHT * ISO_TILE_HALFHEIGHT)); + public void setModel (IsoSceneModel model) + { + _model = model; + _model.calculateXAxis(); + } /** The color to draw the highlighted tile. */ protected static final Color HLT_COLOR = Color.green; @@ -340,29 +372,17 @@ public class IsoSceneView implements EditableSceneView /** The stroke object used to draw the highlighted tile. */ protected static final Stroke HLT_STROKE = new BasicStroke(3); - /** The slope of the x-axis line. */ - protected float SLOPE_X = 0.5f; - - /** The slope of the y-axis line. */ - protected float SLOPE_Y = -0.5f; - - /** The y-intercept of the x-axis line. */ - protected int _bX; - - /** The last calculated x- and y-axis mouse position tracking lines. */ - protected Point _lineX[], _lineY[]; - - /** The bounds dimensions for the view. */ - protected Dimension _bounds; - /** The currently highlighted tile. */ protected Point _htile; /** The font to draw tile coordinates. */ protected Font _font; - /** Whether tile coordinates should be drawn. */ - protected boolean _showCoords; + /** The dirty tile row segments that need to be re-painted. */ + protected ArrayList _dirty; + + /** The scene model data. */ + protected IsoSceneModel _model; /** The scene object to be displayed. */ protected Scene _scene; diff --git a/src/java/com/threerings/miso/client/IsoSceneViewModel.java b/src/java/com/threerings/miso/client/IsoSceneViewModel.java new file mode 100644 index 000000000..06faba593 --- /dev/null +++ b/src/java/com/threerings/miso/client/IsoSceneViewModel.java @@ -0,0 +1,146 @@ +// +// $Id: IsoSceneViewModel.java,v 1.1 2001/08/02 00:42:02 shaper Exp $ + +package com.threerings.miso.scene; + +import java.awt.Dimension; +import java.awt.Point; + +/** + * The IsoSceneModel provides a holding place for the myriad + * parameters and bits of data that describe the details of an + * isometric view of a scene. + * + *

The member data are public to facilitate speedy referencing by + * the IsoSceneView class. Those wishing to set up an + * IsoSceneModel object should do so solely via the constructor and + * accessor methods. + */ +public class IsoSceneModel +{ + /** Tile dimensions and half-dimensions in the view. */ + public int tilewid, tilehei, tilehwid, tilehhei; + + /** The bounds dimensions for the view. */ + public Dimension bounds; + + /** The position in pixels at which tile (0, 0) is drawn. */ + public Point origin; + + /** The total number of tile rows to render the full view. */ + public int tilerows; + + /** The length of a tile edge in pixels. */ + public float tilelen; + + /** The y-intercept of the x-axis line. */ + public int bX; + + /** The last calculated x- and y-axis mouse position tracking lines. */ + public Point lineX[], lineY[]; + + /** Whether tile coordinates should be drawn. */ + public boolean showCoords; + + /** + * Construct an IsoSceneModel with reasonable default values. + */ + public IsoSceneModel () + { + setTileDimensions(32, 16); + setBounds(600, 600); + setOrigin(bounds.width / 2, -(9 * tilehei)); + showCoords = false; + } + + /** + * Set the dimensions of the tiles that comprise the base layer of + * the isometric view and therefore drive the view geometry as a + * whole. + * + * @param width the tile width in pixels. + * @param height the tile height in pixels. + */ + public void setTileDimensions (int width, int height) + { + // save the dimensions + tilewid = width; + tilehei = height; + + // halve the dimensions + tilehwid = width / 2; + tilehhei = height / 2; + + // calculate the length of a tile edge in pixels + tilelen = (float) Math.sqrt( + (tilehwid * tilehwid) + (tilehhei * tilehhei)); + + // calculate the number of tile rows to render + tilerows = (Scene.TILE_WIDTH * Scene.TILE_HEIGHT) - 1; + } + + /** + * Set the origin position at which the isometric view is + * displayed in screen pixel coordinates. + * + * @param x the x-position in pixels. + * @param y the y-position in pixels. + */ + public void setOrigin (int x, int y) + { + // save the requested origin + origin = new Point(x, y); + } + + /** + * Set the desired bounds for the view. The actual resulting + * bounds will be based on the number of whole tiles that fit in + * the requested bounds vertically and horizontally. For the + * bounds to be calculated correctly, therefore, the desired tile + * dimensions should have been previously set via + * setTileDimensions(). + * + * @param width the bounds width in pixels. + * @param height the bounds height in pixels. + */ + public void setBounds (int width, int height) + { + // determine the actual bounds based on the number of whole + // tiles that fit in the requested bounds + int bwid = (width / tilewid) * tilewid; + int bhei = (height / tilehei) * tilehei; + + // save our calculated boundaries in pixel coordinates + bounds = new Dimension(bwid, bhei); + } + + /** + * Pre-calculate the x-axis line (from tile origin to right end of + * x-axis) for later use in converting screen coordinates to tile + * coordinates. + */ + public void calculateXAxis () + { + // create the x- and y-axis lines + lineX = new Point[2]; + lineY = new Point[2]; + for (int ii = 0; ii < 2; ii++) { + lineX[ii] = new Point(); + lineY[ii] = new Point(); + } + + // determine the starting point + lineX[0].setLocation(origin.x, origin.y); + bX = (int)-(SLOPE_X * origin.x); + + // determine the ending point + lineX[1].x = lineX[0].x + (tilehwid * Scene.TILE_WIDTH); + lineX[1].y = lineX[0].y + (int)((SLOPE_X * lineX[1].x) + bX); + } + + /** The slope of the x-axis line. */ + protected final float SLOPE_X = 0.5f; + + /** The slope of the y-axis line. */ + protected final float SLOPE_Y = -0.5f; +} diff --git a/src/java/com/threerings/miso/client/SceneView.java b/src/java/com/threerings/miso/client/SceneView.java index 899e2c2a8..07d8cda50 100644 --- a/src/java/com/threerings/miso/client/SceneView.java +++ b/src/java/com/threerings/miso/client/SceneView.java @@ -1,5 +1,5 @@ // -// $Id: SceneView.java,v 1.7 2001/07/23 18:52:51 shaper Exp $ +// $Id: SceneView.java,v 1.8 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.scene; @@ -7,6 +7,7 @@ import com.threerings.miso.tile.Tile; import java.awt.Component; import java.awt.Graphics; +import java.util.ArrayList; /** * The SceneView interface provides an interface to be implemented by @@ -17,11 +18,23 @@ public interface SceneView { /** * Render the scene to the given graphics context. + * + * @param g the graphics context. */ public void paint (Graphics g); /** * Set the scene that we're rendering. + * + * @param scene the scene to render in the view. */ public void setScene (Scene scene); + + /** + * Invalidate a list of rectangles in screen pixel coordinates in + * the scene view for later repainting. + * + * @param rects the list of java.awt.Rectangle objects. + */ + public void invalidateRects (ArrayList rects); } diff --git a/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/SceneViewPanel.java index a6cc00e5b..5c4bf596a 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.4 2001/07/31 01:38:28 shaper Exp $ +// $Id: SceneViewPanel.java,v 1.5 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.viewer; @@ -14,13 +14,15 @@ import com.threerings.miso.viewer.util.ViewerContext; import com.threerings.miso.scene.*; import com.threerings.miso.scene.xml.XMLFileSceneRepository; import com.threerings.miso.sprite.*; +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. */ public class SceneViewPanel extends JPanel - implements MouseListener, MouseMotionListener + implements MouseListener, MouseMotionListener, PerformanceObserver { /** * Construct the panel and initialize it with a context. @@ -33,7 +35,12 @@ public class SceneViewPanel extends JPanel _sprite = sprite; // construct the view object - _view = new IsoSceneView(_ctx.getTileManager(), spritemgr); + _view = new IsoSceneView(_ctx.getTileManager(), spritemgr, + new IsoSceneModel()); + + // create an animation manager for this panel + AnimationManager animmgr = + new AnimationManager(spritemgr, this, _view); // listen to the desired events addMouseListener(this); @@ -41,6 +48,10 @@ public class SceneViewPanel extends JPanel // load up the initial scene prepareStartingScene(); + + setDoubleBuffered(false); + + PerformanceMonitor.register(this, "paint", 1000); } /** @@ -76,10 +87,24 @@ public class SceneViewPanel extends JPanel /** * Render the panel and the scene view to the given graphics object. */ - public void paint (Graphics g) + public void paintComponent (Graphics g) { - super.paint(g); + Rectangle bounds = getBounds(); + +// Log.info("SceneViewPanel: paint [width=" + bounds.width + +// ", height=" + bounds.height + "]."); + _view.paint(g); + + g.setColor(Color.yellow); + g.drawRect(0, 0, 600, 600); + + PerformanceMonitor.tick(this, "paint"); + } + + public void checkpoint (String name, int ticks) + { + Log.info(name + "[ticks=" + ticks + "]."); } /** MouseListener interface methods */ diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java index be18f093b..42d077830 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java @@ -1,5 +1,5 @@ // -// $Id: ViewerApp.java,v 1.2 2001/07/28 01:31:51 shaper Exp $ +// $Id: ViewerApp.java,v 1.3 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.viewer; @@ -103,7 +103,7 @@ public class ViewerApp /** The desired width and height for the main application window. */ protected static final int WIDTH = 800; - protected static final int HEIGHT = 600; + protected static final int HEIGHT = 622; /** The config object. */ protected Config _config; diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java b/tests/src/java/com/threerings/miso/viewer/ViewerFrame.java index f3fdf2820..b28cee9d0 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.4 2001/07/31 01:38:28 shaper Exp $ +// $Id: ViewerFrame.java,v 1.5 2001/08/02 00:42:02 shaper Exp $ package com.threerings.miso.viewer; @@ -41,16 +41,13 @@ class ViewerFrame extends JFrame implements WindowListener TileManager tilemgr = _ctx.getTileManager(); // add the test character sprite to the sprite manager - MobileSprite ms = new MobileSprite(300, 300, tilemgr, TSID_CHAR); - //ms.setAnimationDelay(10); + MobileSprite ms = + new MobileSprite(spritemgr, 300, 300, tilemgr, TSID_CHAR); 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); - // add the scene view panel getContentPane().add(svpanel, BorderLayout.CENTER); }