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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 <code>NUM_DIRECTIONS</code> rows of tiles, with each
|
||||
* contain <code>Path.NUM_DIRECTIONS</code> rows of tiles, with each
|
||||
* row containing <code>NUM_DIR_FRAMES</code> 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;
|
||||
|
||||
|
||||
@@ -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 <code>setTiles()</code>.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
@@ -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 <code>Sprite.tick()</code> on all sprite objects to give
|
||||
* them a chance to move themselves about, change their display
|
||||
* image, and so forth.
|
||||
* Call <code>tick()</code> 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 <code>PerformanceMonitor</code> class provides a simple
|
||||
* mechanism for monitoring the number of times an action takes place
|
||||
* within a certain time period.
|
||||
*
|
||||
* <p> The action being tracked should be registered with a suitable
|
||||
* name via <code>register()</code>, and <code>tick()</code> should be
|
||||
* called each time the action is performed.
|
||||
*
|
||||
* <p> Whenever <code>tick()</code> 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
|
||||
* <code>PerformanceObserver.checkpoint()</code>.
|
||||
*
|
||||
* <p> Note that this is <em>not</em> 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 <code>checkpoint()</code> method
|
||||
* will never be called until/unless a subsequent call to
|
||||
* <code>tick()</code> 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;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// $Id: PerformanceObserver.java,v 1.1 2001/08/02 00:42:02 shaper Exp $
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
/**
|
||||
* The <code>PerformanceObserver</code> interface should be
|
||||
* implemented by classes that wish to register actions to be
|
||||
* monitored by the <code>PerformanceMonitor</code> class.
|
||||
*/
|
||||
public interface PerformanceObserver
|
||||
{
|
||||
/**
|
||||
* This method is called by the <code>PerformanceMonitor</code>
|
||||
* 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p> The member data are public to facilitate speedy referencing by
|
||||
* the <code>IsoSceneView</code> 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
|
||||
* <code>setTileDimensions()</code>.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
@@ -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 <code>java.awt.Rectangle</code> objects.
|
||||
*/
|
||||
public void invalidateRects (ArrayList rects);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user