From 938445071e191e9f926c497e5d67ceedec572685 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Sat, 27 Apr 2002 18:41:14 +0000 Subject: [PATCH] Removed the last vestiges of the object "layer". Scenes now simply have a list of objects, they can overlap (I think that objects added to a scene later will be rendered before objects added earlier which ends up feeling natural in the editor); no longer are objects ignored when their footprint lies outside the scene bounds. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1302 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../miso/client/DisplayMisoScene.java | 32 +++-- .../miso/client/DisplayMisoSceneImpl.java | 125 ++++++++++-------- .../threerings/miso/client/IsoSceneView.java | 36 +++-- .../miso/tools/EditableMisoScene.java | 45 +++---- .../miso/tools/EditableMisoSceneImpl.java | 118 ++++++++--------- 5 files changed, 178 insertions(+), 178 deletions(-) diff --git a/src/java/com/threerings/miso/client/DisplayMisoScene.java b/src/java/com/threerings/miso/client/DisplayMisoScene.java index 191bd4282..124e1ee3f 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoScene.java +++ b/src/java/com/threerings/miso/client/DisplayMisoScene.java @@ -1,8 +1,11 @@ // -// $Id: DisplayMisoScene.java,v 1.4 2002/02/17 08:01:15 mdb Exp $ +// $Id: DisplayMisoScene.java,v 1.5 2002/04/27 18:41:14 mdb Exp $ package com.threerings.miso.scene; +import java.awt.Point; +import java.util.Iterator; + import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.Tile; import com.threerings.miso.tile.BaseTile; @@ -21,20 +24,31 @@ public interface DisplayMisoScene public BaseTile getBaseTile (int x, int y); /** - * Returns the fring tile at the specified coordinates. + * Returns the fringe tile at the specified coordinates. */ public Tile getFringeTile (int x, int y); /** - * Returns the object tile at the specified coordinates. + * Returns an iterator over all object tiles in this scene. */ - public ObjectTile getObjectTile (int x, int y); + public Iterator getObjectTiles (); /** - * Returns the action associated with the object tile at the specified - * column and row. Null is returned if no object tile exists at that - * column and row or if the object tile that does exist does not have - * an associated action. + * Returns the tile coordinates for the specified object tile. + * + * @param tile the tile for which coordinates are to be fetched; this + * tile must have been obtained from a call to {@link + * #getObjectTiles}. */ - public String getObjectAction (int column, int row); + public Point getObjectCoords (ObjectTile tile); + + /** + * Returns the action associated with the specified object tile. Null + * is returned if the object tile does not have an associated action. + * + * @param tile the tile for which the action is to be fetched; this + * tile must have been obtained from a call to {@link + * #getObjectTiles}. + */ + public String getObjectAction (ObjectTile tile); } diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 793149395..c3a4dc3cc 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,15 +1,18 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.54 2002/04/06 01:52:34 mdb Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.55 2002/04/27 18:41:14 mdb Exp $ package com.threerings.miso.scene; -import com.samskivert.util.HashIntMap; +import java.awt.Point; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + import com.samskivert.util.StringUtil; import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.ObjectTile; -import com.threerings.media.tile.ObjectTileLayer; import com.threerings.media.tile.Tile; import com.threerings.media.tile.TileLayer; @@ -74,20 +77,6 @@ public class DisplayMisoSceneImpl // create the individual tile layer objects _base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei); _fringe = new TileLayer(new Tile[swid*shei], swid, shei); - _object = new ObjectTileLayer(swid, shei); - - // create a mapping for the action strings and populate it - _actions = new HashIntMap(); - for (int i = 0; i < model.objectActions.length; i++) { - String action = model.objectActions[i]; - // skip null or blank actions - if (StringUtil.blank(action)) { - continue; - } - // the key is the composite of the column and row - _actions.put(objectKey(model.objectTileIds[3*i], - model.objectTileIds[3*i+1]), action); - } } /** @@ -152,51 +141,81 @@ public class DisplayMisoSceneImpl "model.objectTileIds.length % 3 != 0"); } - // now populate the object layer - for (int i = 0; i < ocount; i+= 3) { - int col = _model.objectTileIds[i]; - int row = _model.objectTileIds[i+1]; - int tsid = _model.objectTileIds[i+2]; - int tid = (tsid & 0xFFFF); - tsid >>= 16; + // create object tile instances for our objects + _objects = new ArrayList(); + _coords = new HashMap(); + _actions = new HashMap(); - // create the object tile and stick it into the appropriate - // spot in the object layer - ObjectTile otile = (ObjectTile)_tmgr.getTile(tsid, tid); - _object.setTile(col, row, otile); - // generate a "shadow" for this object tile by toggling the - // "covered" flag on in all base tiles below it (to prevent - // sprites from walking on those tiles) - setObjectTileFootprint(otile, col, row, true); + for (int ii = 0; ii < ocount; ii+= 3) { + int col = _model.objectTileIds[ii]; + int row = _model.objectTileIds[ii+1]; + String action = _model.objectActions[ii/3]; + int fqTid = _model.objectTileIds[ii+2]; + int tsid = (fqTid >> 16) & 0xFFFF; + int tid = (fqTid & 0xFFFF); + expandObject(col, row, tsid, tid, fqTid, action); } } - // documentation inherited + /** + * Called to expand each object read from the model into an actual + * object tile instance with the appropriate additional data. + * + * @return the newly created object tile (which will have been put + * into all the appropriate lists and tables). + */ + protected ObjectTile expandObject ( + int col, int row, int tsid, int tid, int fqTid, String action) + throws NoSuchTileException, NoSuchTileSetException + { + // create the object tile and stick it in the list + ObjectTile otile = (ObjectTile)_tmgr.getTile(tsid, tid); + _objects.add(otile); + _coords.put(otile, new Point(col, row)); + + // stick the action in the actions table if there is one + if (!StringUtil.blank(action)) { + _actions.put(otile, action); + } + + // generate a "shadow" for this object tile by toggling the + // "covered" flag on in all base tiles below it (to prevent + // sprites from walking on those tiles) + setObjectTileFootprint(otile, col, row, true); + + // return the object tile so that derived classes have easy access + // to it + return otile; + } + + // documentation inherited from interface public BaseTile getBaseTile (int x, int y) { return _base.getTile(x, y); } - // documentation inherited + // documentation inherited from interface public Tile getFringeTile (int x, int y) { return _fringe.getTile(x, y); } - // documentation inherited - public ObjectTile getObjectTile (int x, int y) + // documentation inherited from interface + public Iterator getObjectTiles () { - return _object.getTile(x, y); + return _objects.iterator(); } // documentation inherited from interface - public String getObjectAction (int column, int row) + public Point getObjectCoords (ObjectTile tile) { - if (_actions != null) { - return (String)_actions.get(objectKey(column, row)); - } else { - return null; - } + return (Point)_coords.get(tile); + } + + // documentation inherited from interface + public String getObjectAction (ObjectTile tile) + { + return (String)_actions.get(tile); } /** @@ -247,15 +266,6 @@ public class DisplayMisoSceneImpl // ", sy=" + y + ", ex=" + endx + ", ey=" + endy + "]."); } - /** - * Computes the action table key for the object at the specified - * column and row. - */ - protected static int objectKey (int column, int row) - { - return (column << 15) + row; - } - /** The tile manager from which we load tiles. */ protected MisoTileManager _tmgr; @@ -268,9 +278,12 @@ public class DisplayMisoSceneImpl /** The fringe layer of tiles. */ protected TileLayer _fringe; - /** The object layer of tiles. */ - protected ObjectTileLayer _object; + /** The object tiles. */ + protected ArrayList _objects; - /** A map from object tile coordinates to action string. */ - protected HashIntMap _actions; + /** A map from object tile to coordinate records. */ + protected HashMap _coords; + + /** A map from object tile to action string. */ + protected HashMap _actions; } diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java index 171f428ad..92c39c5a8 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.106 2002/04/23 01:18:17 mdb Exp $ +// $Id: IsoSceneView.java,v 1.107 2002/04/27 18:41:14 mdb Exp $ package com.threerings.miso.scene; @@ -234,13 +234,13 @@ public class IsoSceneView implements SceneView // if the highlighted object is an object tile, we want to // highlight that if (_hobject instanceof ObjectTile) { + ObjectTile otile = (ObjectTile)_hobject; // if we're only highlighting objects with actions, make sure // this one has an action - String action = _scene.getObjectAction(_hcoords.x, _hcoords.y); + String action = _scene.getObjectAction(otile); if (_hmode != HIGHLIGHT_WITH_ACTION || !StringUtil.blank(action)) { Polygon tpoly = getTilePoly(_hcoords.x, _hcoords.y); - hpoly = IsoUtil.getObjectFootprint( - _model, tpoly, (ObjectTile)_hobject); + hpoly = IsoUtil.getObjectFootprint(_model, tpoly, otile); } } @@ -402,13 +402,11 @@ public class IsoSceneView implements SceneView _objects.clear(); // generate metric records for all objects - for (int yy = 0; yy < _model.scenehei; yy++) { - for (int xx = 0; xx < _model.scenewid; xx++) { - ObjectTile tile = _scene.getObjectTile(xx, yy); - if (tile != null) { - generateObjectMetrics(tile, xx, yy); - } - } + Iterator oiter = _scene.getObjectTiles(); + while (oiter.hasNext()) { + ObjectTile tile = (ObjectTile)oiter.next(); + Point coords = _scene.getObjectCoords(tile); + generateObjectMetrics(tile, coords.x, coords.y); } } @@ -431,15 +429,15 @@ public class IsoSceneView implements SceneView } /** - * Clears out the object metrics for the object at the specified tile - * coordinates. + * Clears out the object metrics for the specified object. */ - protected void clearObjectMetrics (int x, int y) + protected void clearObjectMetrics (ObjectTile tile) { - for (int i = 0; i < _objects.size(); i++) { - ObjectMetrics metrics = (ObjectMetrics)_objects.get(i); - if (metrics.x == x && metrics.y == y) { - _objects.remove(i); + int ocount = _objects.size(); + for (int ii = 0; ii < ocount; ii++) { + ObjectMetrics metrics = (ObjectMetrics)_objects.get(ii); + if (metrics.tile == tile) { + _objects.remove(ii); return; } } @@ -751,7 +749,7 @@ public class IsoSceneView implements SceneView // to repaint if the object has an action if (_hmode != HIGHLIGHT_NEVER) { repaint = (_hmode == HIGHLIGHT_WITH_ACTION) ? - (_scene.getObjectAction(_hcoords.x, _hcoords.y) != null) : + (_scene.getObjectAction((ObjectTile)_hobject) != null) : true; } } diff --git a/src/java/com/threerings/miso/tools/EditableMisoScene.java b/src/java/com/threerings/miso/tools/EditableMisoScene.java index 20f2d73e3..e1939930b 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoScene.java +++ b/src/java/com/threerings/miso/tools/EditableMisoScene.java @@ -1,5 +1,5 @@ // -// $Id: EditableMisoScene.java,v 1.14 2002/04/09 18:06:37 ray Exp $ +// $Id: EditableMisoScene.java,v 1.15 2002/04/27 18:41:14 mdb Exp $ package com.threerings.miso.scene.tools; @@ -7,6 +7,7 @@ import java.awt.Rectangle; import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.Tile; +import com.threerings.media.tile.TileUtil; import com.threerings.miso.tile.BaseTile; import com.threerings.miso.tile.BaseTileSet; @@ -35,8 +36,7 @@ public interface EditableMisoScene * * @param defaultBaseTile the new default base tile. * @param fqTileId the fully-qualified tile id (@see - * com.threerings.media.tile.TileUtil#getFQTileId}) of the new default - * base tile. + * TileUtil#getFQTileId}) of the new default base tile. */ public void setDefaultBaseTileSet (BaseTileSet defaultBaseTileSet, int setId); @@ -48,8 +48,7 @@ public interface EditableMisoScene * @param y the y-coordinate of the tile to set. * @param tile the tile to set. * @param fqTileId the fully-qualified tile id (@see - * com.threerings.media.tile.TileUtil#getFQTileId}) of the new default - * base tile. + * TileUtil#getFQTileId}) of the new default base tile. */ public void setBaseTile (int x, int y, BaseTile tile, int fqTileId); @@ -66,34 +65,25 @@ public interface EditableMisoScene * @param y the y-coordinate of the tile to set. * @param tile the tile to set. * @param fqTileId the fully-qualified tile id (@see - * com.threerings.media.tile.TileUtil#getFQTileId}) of the new default - * base tile. + * TileUtil#getFQTileId}) of the new default base tile. */ public void setFringeTile (int x, int y, Tile tile, int fqTileId); /** - * Updates the tile at the specified location in the object layer. Any - * previous object tile at that location should be cleared out by the - * implementation of this method before the new tile is set to ensure - * that footprint tiles associated with the old object are properly - * disposed of. + * Addds an object tile to this scene. * - * @param x the x-coordinate of the tile to set. - * @param y the y-coordinate of the tile to set. + * @param x the object's origin x-coordinate. + * @param y the object's origin y-coordinate. * @param tile the tile to set. * @param fqTileId the fully-qualified tile id (@see - * com.threerings.media.tile.TileUtil#getFQTileId}) of the new default - * base tile. + * TileUtil#getFQTileId}) of the new default base tile. */ - public void setObjectTile (int x, int y, ObjectTile tile, int fqTileId); + public void addObjectTile (ObjectTile tile, int x, int y, int fqTileId); /** - * Sets the action string for the object tile at the specified - * coordinates. It may be assumed by the implementation that an object - * tile exists in the scene at the specified coordinates, thus callers - * should be sure only to call this method accordingly. + * Sets the action string for the specified object tile. */ - public void setObjectAction (int x, int y, String action); + public void setObjectAction (ObjectTile tile, String action); /** * Clears out the tile at the specified location in the base layer. @@ -106,17 +96,14 @@ public interface EditableMisoScene public void clearFringeTile (int x, int y); /** - * Clears out the tile at the specified location in the object layer. + * Clears out the specified tile from the object list. */ - public void clearObjectTile (int x, int y); + public void removeObjectTile (ObjectTile tile); /** - * Clears the action string for the object tile at the specified - * coordinates. It may be assumed by the implementation that an object - * tile exists in the scene at the specified coordinates, thus callers - * should be sure only to call this method accordingly. + * Clears the action string for the specified object tile. */ - public void clearObjectAction (int x, int y); + public void clearObjectAction (ObjectTile tile); /** * Returns a reference to the miso scene model that reflects the diff --git a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java index 1139aa0d1..35dbfc21e 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java +++ b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java @@ -1,14 +1,15 @@ // -// $Id: EditableMisoSceneImpl.java,v 1.16 2002/04/09 18:06:37 ray Exp $ +// $Id: EditableMisoSceneImpl.java,v 1.17 2002/04/27 18:41:14 mdb Exp $ package com.threerings.miso.scene.tools; +import java.awt.Point; import java.awt.Rectangle; + +import java.util.HashMap; import java.util.Iterator; import java.util.Random; -import com.samskivert.util.HashIntMap; - import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.ObjectTile; @@ -48,7 +49,6 @@ public class EditableMisoSceneImpl { super(model, tmgr); _fringer = tmgr.getAutoFringer(); - unpackObjectLayer(); } /** @@ -62,14 +62,12 @@ public class EditableMisoSceneImpl public EditableMisoSceneImpl (MisoSceneModel model) { super(model); - unpackObjectLayer(); } // documentation inherited public void setMisoSceneModel (MisoSceneModel model) { super.setMisoSceneModel(model); - unpackObjectLayer(); } // documentation inherited @@ -127,27 +125,22 @@ public class EditableMisoSceneImpl } // documentation inherited - public void setObjectTile (int x, int y, ObjectTile tile, int fqTileId) + public void addObjectTile (ObjectTile tile, int x, int y, int fqTileId) { - ObjectTile prev = _object.getTile(x, y); - // clear out any previous tile to ensure that everything is - // properly cleaned up - if (prev != null) { - clearObjectTile(x, y); - } - // stick the new object into the layer - _object.setTile(x, y, tile); + // add the tile to the list + _objects.add(tile); + _coords.put(tile, new Point(x, y)); + _objectTileIds.put(tile, new Integer(fqTileId)); + // toggle the "covered" flag on in all base tiles below this // object tile setObjectTileFootprint(tile, x, y, true); - // stick this value into our non-sparse object layer - _objectTileIds.put(IsoUtil.coordsToKey(x, y), new Integer(fqTileId)); } // documentation inherited from interface - public void setObjectAction (int x, int y, String action) + public void setObjectAction (ObjectTile tile, String action) { - _actions.put(objectKey(x, y), action); + _actions.put(tile, action); } // documentation inherited @@ -167,26 +160,25 @@ public class EditableMisoSceneImpl } // documentation inherited - public void clearObjectTile (int x, int y) + public void removeObjectTile (ObjectTile tile) { - ObjectTile tile = _object.getTile(x, y); - if (tile != null) { + // remove the tile from the list and tables + _objects.remove(tile); + _actions.remove(tile); + _objectTileIds.remove(tile); + + Point p = (Point)_coords.remove(tile); + if (p != null) { // toggle the "covered" flag off on the base tiles in this // object tile's footprint - setObjectTileFootprint(tile, x, y, false); - // clear out the tile itself - _object.clearTile(x, y); + setObjectTileFootprint(tile, p.x, p.y, false); } - // clear it out in our non-sparse array - _objectTileIds.remove(IsoUtil.coordsToKey(x, y)); - // clear out any action for this tile as well - _actions.remove(objectKey(x, y)); } // documentation inherited from interface - public void clearObjectAction (int x, int y) + public void clearObjectAction (ObjectTile tile) { - _actions.remove(objectKey(x, y)); + _actions.remove(tile); } // documentation inherited @@ -194,24 +186,17 @@ public class EditableMisoSceneImpl { // we need to flush the object layer to the model prior to // returning it - int otileCount = _objectTileIds.size(); - int cols = _object.getWidth(); - int rows = _object.getHeight(); + int ocount = _objects.size(); + int[] otids = new int[ocount*3]; + String[] actions = new String[ocount]; - // now create and populate the new tileid and actions arrays - int[] otids = new int[otileCount*3]; - String[] actions = new String[otileCount]; - int otidx = 0, actidx = 0; - - Iterator keys = _objectTileIds.keys(); - while (keys.hasNext()) { - int key = ((Integer) keys.next()).intValue(); - int c = IsoUtil.xCoordFromKey(key); - int r = IsoUtil.yCoordFromKey(key); - otids[otidx++] = c; - otids[otidx++] = r; - otids[otidx++] = ((Integer) _objectTileIds.get(key)).intValue(); - actions[actidx++] = (String)_actions.get(objectKey(c, r)); + for (int ii = 0; ii < ocount; ii++) { + ObjectTile tile = (ObjectTile)_objects.get(ii); + Point coords = (Point)_coords.get(tile); + otids[3*ii] = coords.x; + otids[3*ii+1] = coords.y; + otids[3*ii+2] = ((Integer)_objectTileIds.get(tile)).intValue(); + actions[ii] = (String)_actions.get(tile); } // stuff the new arrays into the model @@ -222,28 +207,31 @@ public class EditableMisoSceneImpl return _model; } - /** - * Unpacks the object layer into an array that we can update along - * with the other layers. - */ - protected void unpackObjectLayer () + // documentation inherited + protected ObjectTile expandObject ( + int col, int row, int tsid, int tid, int fqTid, String action) + throws NoSuchTileException, NoSuchTileSetException { - // we need this to track object layer mods - _objectTileIds = new HashIntMap(); + // do the actual object creation + ObjectTile tile = super.expandObject( + col, row, tsid, tid, fqTid, action); - // populate our non-spare array - int[] otids = _model.objectTileIds; - for (int i = 0; i < otids.length; i += 3) { - int x = otids[i]; - int y = otids[i+1]; - int fqTileId = otids[i+2]; - _objectTileIds.put(IsoUtil.coordsToKey(x, y), - new Integer(fqTileId)); + // make sure our array is created (we have to do this specially + // here because this method is called before our constructor is + // called; yay Java!) + if (_objectTileIds == null) { + _objectTileIds = new HashMap(); } + + // we need this to track object layer mods + _objectTileIds.put(tile, new Integer(fqTid)); + + // pass on the objecty goodness + return tile; } - /** where we keep track of object tile ids. */ - protected HashIntMap _objectTileIds; + /** Where we keep track of object tile ids. */ + protected HashMap _objectTileIds = new HashMap(); /** The default tileset with which to fill the base layer. */ protected BaseTileSet _defaultBaseTileSet;