Store object tiles in HashIntMaps instead of in arrays because they may

have coordinates outside of the normal scene coordinates.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1150 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-03-26 20:17:51 +00:00
parent 5f42e8d304
commit aca95b8540
5 changed files with 83 additions and 49 deletions
@@ -1,8 +1,12 @@
// //
// $Id: ObjectTileLayer.java,v 1.1 2001/11/18 04:09:21 mdb Exp $ // $Id: ObjectTileLayer.java,v 1.2 2002/03/26 20:17:51 ray Exp $
package com.threerings.media.tile; package com.threerings.media.tile;
import com.samskivert.util.HashIntMap;
import com.threerings.miso.scene.util.IsoUtil;
/** /**
* The object tile layer class is a convenience class provided to simplify * The object tile layer class is a convenience class provided to simplify
* the management of a two-dimensional array of object tiles. It takes * the management of a two-dimensional array of object tiles. It takes
@@ -24,15 +28,8 @@ public final class ObjectTileLayer
* @exception IllegalArgumentException thrown if the size of the tiles * @exception IllegalArgumentException thrown if the size of the tiles
* array does not match the specified width and height. * array does not match the specified width and height.
*/ */
public ObjectTileLayer (ObjectTile[] tiles, int width, int height) public ObjectTileLayer (int width, int height)
{ {
// sanity check
if (tiles.length != width*height) {
String errmsg = "tiles.length != width*height";
throw new IllegalArgumentException(errmsg);
}
_tiles = tiles;
_width = width; _width = width;
_height = height; _height = height;
} }
@@ -60,7 +57,7 @@ public final class ObjectTileLayer
*/ */
public ObjectTile getTile (int column, int row) public ObjectTile getTile (int column, int row)
{ {
return _tiles[row*_width+column]; return (ObjectTile) _tiles.get(IsoUtil.coordsToKey(column, row));
} }
/** /**
@@ -70,11 +67,19 @@ public final class ObjectTileLayer
*/ */
public void setTile (int column, int row, ObjectTile tile) public void setTile (int column, int row, ObjectTile tile)
{ {
_tiles[row*_width+column] = tile; _tiles.put(IsoUtil.coordsToKey(column, row), tile);
} }
/** Our tiles array. */ /**
private ObjectTile[] _tiles; * Removes the tile at the specified row and column
*/
public void clearTile (int column, int row)
{
_tiles.remove(IsoUtil.coordsToKey(column, row));
}
/** Our tiles. */
private HashIntMap _tiles = new HashIntMap();
/** The number of tiles in a row. */ /** The number of tiles in a row. */
private int _width; private int _width;
@@ -1,5 +1,5 @@
// //
// $Id: DisplayMisoSceneImpl.java,v 1.51 2002/02/17 08:01:15 mdb Exp $ // $Id: DisplayMisoSceneImpl.java,v 1.52 2002/03/26 20:17:51 ray Exp $
package com.threerings.miso.scene; package com.threerings.miso.scene;
@@ -74,7 +74,7 @@ public class DisplayMisoSceneImpl
// create the individual tile layer objects // create the individual tile layer objects
_base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei); _base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei);
_fringe = new TileLayer(new Tile[swid*shei], swid, shei); _fringe = new TileLayer(new Tile[swid*shei], swid, shei);
_object = new ObjectTileLayer(new ObjectTile[swid*shei], swid, shei); _object = new ObjectTileLayer(swid, shei);
// create a mapping for the action strings and populate it // create a mapping for the action strings and populate it
_actions = new HashIntMap(); _actions = new HashIntMap();
@@ -227,7 +227,11 @@ public class DisplayMisoSceneImpl
int endy = Math.max(0, (y - otile.getBaseHeight() + 1)); int endy = Math.max(0, (y - otile.getBaseHeight() + 1));
for (int xx = x; xx >= endx; xx--) { for (int xx = x; xx >= endx; xx--) {
if ((xx < 0) || (xx >= _model.width)) continue;
for (int yy = y; yy >= endy; yy--) { for (int yy = y; yy >= endy; yy--) {
if ((yy < 0) || (yy >= _model.height)) continue;
BaseTile tile = _base.getTile(xx, yy); BaseTile tile = _base.getTile(xx, yy);
if (tile != null) { if (tile != null) {
tile.setCovered(covered); tile.setCovered(covered);
@@ -1,5 +1,5 @@
// //
// $Id: IsoSceneView.java,v 1.102 2002/03/16 03:15:05 shaper Exp $ // $Id: IsoSceneView.java,v 1.103 2002/03/26 20:17:51 ray Exp $
package com.threerings.miso.scene; package com.threerings.miso.scene;
@@ -22,6 +22,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.samskivert.util.HashIntMap;
import com.threerings.media.animation.AnimationManager; import com.threerings.media.animation.AnimationManager;
import com.threerings.media.sprite.Path; import com.threerings.media.sprite.Path;
@@ -77,7 +78,7 @@ public class IsoSceneView implements SceneView
// create our polygon arrays, these will be populated with the // create our polygon arrays, these will be populated with the
// tile polygons as they are requested // tile polygons as they are requested
_polys = new Polygon[model.scenewid][model.scenehei]; _polys = new HashIntMap();
// create the array used to mark dirty tiles // create the array used to mark dirty tiles
_dirty = new boolean[model.scenewid][model.tilehei]; _dirty = new boolean[model.scenewid][model.tilehei];
@@ -502,9 +503,12 @@ public class IsoSceneView implements SceneView
*/ */
protected Polygon getTilePoly (int x, int y) protected Polygon getTilePoly (int x, int y)
{ {
Polygon poly = _polys[x][y]; int key = IsoUtil.coordsToKey(x, y);
Polygon poly = (Polygon) _polys.get(key);
if (poly == null) { if (poly == null) {
poly = _polys[x][y] = IsoUtil.getTilePolygon(_model, x, y); poly = IsoUtil.getTilePolygon(_model, x, y);
_polys.put(key, poly);
} }
return poly; return poly;
} }
@@ -933,7 +937,7 @@ public class IsoSceneView implements SceneView
protected DisplayMisoScene _scene; protected DisplayMisoScene _scene;
/** Polygon outlines for all of our base tiles. */ /** Polygon outlines for all of our base tiles. */
protected Polygon _polys[][]; protected HashIntMap _polys;
/** Metric information for all of the object tiles. */ /** Metric information for all of the object tiles. */
protected ArrayList _objects = new ArrayList(); protected ArrayList _objects = new ArrayList();
@@ -1,5 +1,5 @@
// //
// $Id: IsoUtil.java,v 1.22 2002/03/16 03:15:06 shaper Exp $ // $Id: IsoUtil.java,v 1.23 2002/03/26 20:17:51 ray Exp $
package com.threerings.miso.scene.util; package com.threerings.miso.scene.util;
@@ -446,6 +446,30 @@ public class IsoUtil
return poly; return poly;
} }
/**
* @return the hash key, give x and y
*/
public static final int coordsToKey (int x, int y)
{
return ((y << 16) & (0xFFFF0000)) | (x & 0xFFFF);
}
/**
* @return the x coordinate from the hash key
*/
public static final int xCoordFromKey (int key)
{
return (key & 0xFFFF);
}
/**
* @return the y coordinate from the hash key
*/
public static final int yCoordFromKey (int key)
{
return ((key >> 16) & 0xFFFF);
}
/** Multiplication factor to embed tile coords in full coords. */ /** Multiplication factor to embed tile coords in full coords. */
protected static final int FULL_TILE_FACTOR = 100; protected static final int FULL_TILE_FACTOR = 100;
} }
@@ -1,8 +1,10 @@
// //
// $Id: EditableMisoSceneImpl.java,v 1.9 2002/02/06 17:13:06 mdb Exp $ // $Id: EditableMisoSceneImpl.java,v 1.10 2002/03/26 20:17:51 ray Exp $
package com.threerings.miso.scene.tools; package com.threerings.miso.scene.tools;
import com.samskivert.util.HashIntMap;
import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileException;
import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.NoSuchTileSetException;
import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.ObjectTile;
@@ -13,6 +15,9 @@ import com.threerings.miso.tile.BaseTile;
import com.threerings.miso.scene.DisplayMisoSceneImpl; import com.threerings.miso.scene.DisplayMisoSceneImpl;
import com.threerings.miso.scene.MisoSceneModel; import com.threerings.miso.scene.MisoSceneModel;
import com.threerings.miso.scene.util.IsoUtil;
import java.util.Iterator;
/** /**
* The default implementation of the {@link EditableMisoScene} interface. * The default implementation of the {@link EditableMisoScene} interface.
@@ -103,7 +108,7 @@ public class EditableMisoSceneImpl
// object tile // object tile
setObjectTileFootprint(tile, x, y, true); setObjectTileFootprint(tile, x, y, true);
// stick this value into our non-sparse object layer // stick this value into our non-sparse object layer
_objectTileIds[_model.width*y + x] = fqTileId; _objectTileIds.put(IsoUtil.coordsToKey(x, y), new Integer(fqTileId));
} }
// documentation inherited from interface // documentation inherited from interface
@@ -137,10 +142,10 @@ public class EditableMisoSceneImpl
// object tile's footprint // object tile's footprint
setObjectTileFootprint(tile, x, y, false); setObjectTileFootprint(tile, x, y, false);
// clear out the tile itself // clear out the tile itself
_object.setTile(x, y, null); _object.clearTile(x, y);
} }
// clear it out in our non-sparse array // clear it out in our non-sparse array
_objectTileIds[_model.width*y + x] = 0; _objectTileIds.remove(IsoUtil.coordsToKey(x, y));
// clear out any action for this tile as well // clear out any action for this tile as well
_actions.remove(objectKey(x, y)); _actions.remove(objectKey(x, y));
} }
@@ -156,32 +161,24 @@ public class EditableMisoSceneImpl
{ {
// we need to flush the object layer to the model prior to // we need to flush the object layer to the model prior to
// returning it // returning it
int otileCount = 0; int otileCount = _objectTileIds.size();
int cols = _object.getWidth(); int cols = _object.getWidth();
int rows = _object.getHeight(); int rows = _object.getHeight();
// first count how many object tiles we have
for (int i = 0; i < _objectTileIds.length; i++) {
if (_objectTileIds[i] != 0) {
otileCount++;
}
}
// now create and populate the new tileid and actions arrays // now create and populate the new tileid and actions arrays
int[] otids = new int[otileCount*3]; int[] otids = new int[otileCount*3];
String[] actions = new String[otileCount]; String[] actions = new String[otileCount];
int otidx = 0, actidx = 0; int otidx = 0, actidx = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) { Iterator keys = _objectTileIds.keys();
int tsid = _objectTileIds[_model.width*r + c]; while (keys.hasNext()) {
if (tsid == 0) { int key = ((Integer) keys.next()).intValue();
continue; int c = IsoUtil.xCoordFromKey(key);
} int r = IsoUtil.yCoordFromKey(key);
otids[otidx++] = c; otids[otidx++] = c;
otids[otidx++] = r; otids[otidx++] = r;
otids[otidx++] = tsid; otids[otidx++] = ((Integer) _objectTileIds.get(key)).intValue();
actions[actidx++] = (String)_actions.get(objectKey(c, r)); actions[actidx++] = (String)_actions.get(objectKey(c, r));
}
} }
// stuff the new arrays into the model // stuff the new arrays into the model
@@ -199,7 +196,7 @@ public class EditableMisoSceneImpl
protected void unpackObjectLayer () protected void unpackObjectLayer ()
{ {
// we need this to track object layer mods // we need this to track object layer mods
_objectTileIds = new int[_model.baseTileIds.length]; _objectTileIds = new HashIntMap();
// populate our non-spare array // populate our non-spare array
int[] otids = _model.objectTileIds; int[] otids = _model.objectTileIds;
@@ -207,13 +204,13 @@ public class EditableMisoSceneImpl
int x = otids[i]; int x = otids[i];
int y = otids[i+1]; int y = otids[i+1];
int fqTileId = otids[i+2]; int fqTileId = otids[i+2];
_objectTileIds[_model.width*y + x] = fqTileId; _objectTileIds.put(IsoUtil.coordsToKey(x, y),
new Integer(fqTileId));
} }
} }
/** A non-sparse array where we can keep track of the object tile /** where we keep track of object tile ids. */
* ids. */ protected HashIntMap _objectTileIds;
protected int[] _objectTileIds;
/** The default tile with which to fill the base layer. */ /** The default tile with which to fill the base layer. */
protected BaseTile _defaultBaseTile; protected BaseTile _defaultBaseTile;