Refactored Miso scene system to support larger (tiled) scenes in the
future. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2268 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// $Id: MisoScene.java,v 1.1 2003/02/12 05:39:15 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.threerings.miso.client.util.ObjectSet;
|
||||
|
||||
/**
|
||||
* Provides information on the composition of tiles in a Miso scene.
|
||||
*/
|
||||
public interface MisoScene
|
||||
{
|
||||
/**
|
||||
* Returns the fully qualified tile id of the base tile at the
|
||||
* specified coordinates. <code>-1</code> will be returned if there is
|
||||
* no tile at the specified coordinate.
|
||||
*/
|
||||
public int getBaseTileId (int x, int y);
|
||||
|
||||
/**
|
||||
* Populates the supplied object set with info on all objects whose
|
||||
* origin falls in the requested region.
|
||||
*/
|
||||
public void getObjects (Rectangle region, ObjectSet set);
|
||||
|
||||
/**
|
||||
* Updates the tile at the specified location in the base layer.
|
||||
*
|
||||
* @param fqTileId the fully-qualified tile id (@see
|
||||
* TileUtil#getFQTileId}) of the tile to set.
|
||||
* @param x the x-coordinate of the tile to set.
|
||||
* @param y the y-coordinate of the tile to set.
|
||||
*/
|
||||
public void setBaseTile (int fqTileId, int x, int y);
|
||||
|
||||
/**
|
||||
* Fill a rectangular area with random tiles from the specified base
|
||||
* tileset.
|
||||
*
|
||||
* @param r the region to be filled.
|
||||
* @param setId the id of the tileset to use when filling.
|
||||
* @param setSize the number of tiles in the tileset.
|
||||
*/
|
||||
public void setBaseTiles (Rectangle r, int setId, int setSize);
|
||||
|
||||
/**
|
||||
* Adds an object to this scene.
|
||||
*
|
||||
* @param fqTileId the fully-qualified tile id (@see
|
||||
* TileUtil#getFQTileId}) of the object tile.
|
||||
* @param x the object's origin x-coordinate.
|
||||
* @param y the object's origin y-coordinate.
|
||||
*
|
||||
* @return the new object info record.
|
||||
*/
|
||||
public ObjectInfo addObject (int fqTileId, int x, int y);
|
||||
|
||||
/**
|
||||
* Removes the specified object from the scene.
|
||||
*/
|
||||
public boolean removeObject (ObjectInfo info);
|
||||
|
||||
/**
|
||||
* Returns the scene model used by this scene.
|
||||
*/
|
||||
public MisoSceneModel getSceneModel ();
|
||||
}
|
||||
@@ -1,213 +1,56 @@
|
||||
//
|
||||
// $Id: MisoSceneModel.java,v 1.11 2003/01/31 23:10:45 mdb Exp $
|
||||
// $Id: MisoSceneModel.java,v 1.12 2003/02/12 05:39:15 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
/**
|
||||
* The scene model is the bare bones representation of the data for a
|
||||
* scene in the Miso system. From the scene model, one would create an
|
||||
* instance of {@link DisplayMisoScene}.
|
||||
* Contains basic information for a miso scene model that is shared among
|
||||
* every specialized model implementation.
|
||||
*/
|
||||
public class MisoSceneModel extends SimpleStreamableObject
|
||||
implements Cloneable
|
||||
{
|
||||
/** The width of the scene in tile units. */
|
||||
/** The sector of our containing scene for which we contain model
|
||||
* data. Simple scenes may contain only one sector, but larger more
|
||||
* complicated scenes will likely contain multiple sectors to support
|
||||
* fine grain updates. */
|
||||
public int sectorId;
|
||||
|
||||
/** The width of our sector, in tile units. */
|
||||
public int width;
|
||||
|
||||
/** The height of the scene in tile units. */
|
||||
/** The height of our sector, in tile units. */
|
||||
public int height;
|
||||
|
||||
/** The viewport width in tiles. */
|
||||
public int vwidth;
|
||||
|
||||
/** The viewport height in tiles. */
|
||||
public int vheight;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) in compressed
|
||||
* format. Don't go poking around in here, use the accessor
|
||||
* methods. */
|
||||
public int[] baseTileIds;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) of the
|
||||
* "uninteresting" tiles in the object layer. */
|
||||
public int[] objectTileIds;
|
||||
|
||||
/** The x coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectXs;
|
||||
|
||||
/** The y coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectYs;
|
||||
|
||||
/** Information records for the "interesting" objects in the object
|
||||
* layer. */
|
||||
public ObjectInfo[] objectInfo;
|
||||
|
||||
/**
|
||||
* Get the fully-qualified tile id of the base tile at the specified
|
||||
* row and column.
|
||||
* Creates a completely uninitialized model suitable for little more
|
||||
* than unserialization.
|
||||
*/
|
||||
public int getBaseTile (int col, int row)
|
||||
public MisoSceneModel ()
|
||||
{
|
||||
int index = getIndex(col, row);
|
||||
return (index == -1) ? 0 : baseTileIds[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fully-qualified tile id of a base tile.
|
||||
*
|
||||
* @return false if the specified tile coordinates are outside
|
||||
* of the viewport and the tile was not saved.
|
||||
* Creates a blank model with the specified dimensions.
|
||||
*/
|
||||
public boolean setBaseTile (int col, int row, int fqBaseTileId)
|
||||
public MisoSceneModel (int width, int height)
|
||||
{
|
||||
int index = getIndex(col, row);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
baseTileIds[index] = fqBaseTileId;
|
||||
return true;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index into the baseTileIds[] for the specified
|
||||
* x and y coordinates, or return -1 if the specified coordinates
|
||||
* are outside of the viewable area.
|
||||
*
|
||||
* Assumption: The viewable area is centered and aligned as far
|
||||
* to the top of the isometric scene as possible, such that
|
||||
* the upper-left corner is at the point where the tiles
|
||||
* (0, vwid) and (0, vwid-1) touch. The upper-right corner
|
||||
* is at the point where the tiles (vwid-1, 0) and (vwid, 0)
|
||||
* touch.
|
||||
*
|
||||
* The viewable area is made up of "fat" rows and "thin" rows. The
|
||||
* fat rows display one more tile than the thin rows because their
|
||||
* first and last tiles are halfway off the viewable area. The thin
|
||||
* rows are fully contained within the viewable area except for the
|
||||
* first and last thin rows, which display only their bottom and top
|
||||
* halves, respectively. Note that #fatrows == #thinrows - 1;
|
||||
*/
|
||||
protected int getIndex (int x, int y)
|
||||
{
|
||||
// check to see if the index lies in one of the "fat" rows
|
||||
if (((x + y) & 1) == (vwidth & 1)) {
|
||||
|
||||
int col = (vwidth + x - y) >> 1;
|
||||
int row = x - col;
|
||||
if ((col < 0) || (col > vwidth) ||
|
||||
(row < 0) || (row >= vheight)) {
|
||||
return -1; // out of view
|
||||
}
|
||||
|
||||
return (vwidth + 1) * row + col;
|
||||
|
||||
} else {
|
||||
// the index must be in a "thin" row
|
||||
int col = (vwidth + x - y - 1) >> 1;
|
||||
int row = x - col;
|
||||
if ((col < 0) || (col >= vwidth) ||
|
||||
(row < 0) || (row > vheight)) {
|
||||
return -1; // out of view
|
||||
}
|
||||
|
||||
// we store the all the fat rows first, then all the thin
|
||||
// rows, the '(vwidth + 1) * vheight' is the size of all
|
||||
// the fat rows.
|
||||
return row * vwidth + col + (vwidth + 1) * vheight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the base tile array.
|
||||
*/
|
||||
protected void allocateBaseTileArray ()
|
||||
{
|
||||
baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this Miso scene model.
|
||||
* Creates a copy of this scene model.
|
||||
*/
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
MisoSceneModel model = (MisoSceneModel)super.clone();
|
||||
model.baseTileIds = (int[])baseTileIds.clone();
|
||||
model.objectTileIds = (int[])objectTileIds.clone();
|
||||
model.objectXs = (short[])objectXs.clone();
|
||||
model.objectYs = (short[])objectYs.clone();
|
||||
model.objectInfo = (ObjectInfo[])objectInfo.clone();
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the interesting and uninteresting parts of a miso scene
|
||||
* model given lists of {@link ObjectInfo} records for each.
|
||||
*/
|
||||
public static void populateObjects (MisoSceneModel model,
|
||||
ArrayList ilist, ArrayList ulist)
|
||||
{
|
||||
// set up the uninteresting arrays
|
||||
int ucount = ulist.size();
|
||||
model.objectTileIds = new int[ucount];
|
||||
model.objectXs = new short[ucount];
|
||||
model.objectYs = new short[ucount];
|
||||
for (int ii = 0; ii < ucount; ii++) {
|
||||
ObjectInfo info = (ObjectInfo)ulist.get(ii);
|
||||
model.objectTileIds[ii] = info.tileId;
|
||||
model.objectXs[ii] = (short)info.x;
|
||||
model.objectYs[ii] = (short)info.y;
|
||||
try {
|
||||
return (MisoSceneModel)super.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException(
|
||||
"MisoSceneModel.clone() booched " + cnse);
|
||||
}
|
||||
|
||||
// set up the interesting array
|
||||
int icount = ilist.size();
|
||||
model.objectInfo = new ObjectInfo[icount];
|
||||
ilist.toArray(model.objectInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank scene model (with zero width and
|
||||
* height).
|
||||
*/
|
||||
public static MisoSceneModel blankMisoSceneModel ()
|
||||
{
|
||||
MisoSceneModel model = new MisoSceneModel();
|
||||
populateBlankMisoSceneModel(model, 0, 0, 0, 0);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank scene model with the specified width
|
||||
* and height.
|
||||
*/
|
||||
public static MisoSceneModel blankMisoSceneModel (
|
||||
int width, int height, int vwidth, int vheight)
|
||||
{
|
||||
MisoSceneModel model = new MisoSceneModel();
|
||||
populateBlankMisoSceneModel(model, width, height, vwidth, vheight);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a blank scene model with blank values.
|
||||
*/
|
||||
protected static void populateBlankMisoSceneModel (
|
||||
MisoSceneModel model, int width, int height, int vwidth, int vheight)
|
||||
{
|
||||
model.width = width;
|
||||
model.height = height;
|
||||
model.vwidth = vwidth;
|
||||
model.vheight = vheight;
|
||||
model.allocateBaseTileArray();
|
||||
model.objectTileIds = new int[0];
|
||||
model.objectXs = new short[0];
|
||||
model.objectYs = new short[0];
|
||||
model.objectInfo = new ObjectInfo[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// $Id: MisoSceneRepository.java,v 1.1 2003/02/12 05:39:15 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
/**
|
||||
* A generic interface for an entity that provides access to {@link
|
||||
* MisoSceneModel} data.
|
||||
*/
|
||||
public interface MisoSceneRepository
|
||||
{
|
||||
/**
|
||||
* Loads the specified scene model from the repository.
|
||||
*
|
||||
* @return the requested scene or null if no scene exists with the
|
||||
* specified scene and sector id.
|
||||
*
|
||||
* @exception PersistenceException thrown if an error occurs
|
||||
* communicating with the underlying storage mechanism.
|
||||
*/
|
||||
public MisoSceneModel loadSceneModel (int sceneId, int sectorId)
|
||||
throws PersistenceException;
|
||||
|
||||
/**
|
||||
* Stores the specified model in the repository, inserting it if it
|
||||
* does not already exist, updating it otherwise.
|
||||
*
|
||||
* @exception PersistenceException thrown if an error occurs
|
||||
* communicating with the underlying storage mechanism.
|
||||
*/
|
||||
public void storeSceneModel (MisoSceneModel model)
|
||||
throws PersistenceException;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// $Id: SimpleMisoSceneImpl.java,v 1.1 2003/02/12 05:39:15 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import com.threerings.media.tile.TileUtil;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
import com.threerings.miso.client.util.ObjectSet;
|
||||
|
||||
/**
|
||||
* A simple implementation of the {@link MisoScene} interface that assumes
|
||||
* a scene will be relatively small and all tile and object data can be
|
||||
* held in memory all at once.
|
||||
*/
|
||||
public class SimpleMisoSceneImpl
|
||||
implements MisoScene
|
||||
{
|
||||
/**
|
||||
* Creates an initializes an instance using the supplied source model.
|
||||
*/
|
||||
public SimpleMisoSceneImpl (SimpleMisoSceneModel model)
|
||||
{
|
||||
_model = model;
|
||||
|
||||
// create display object infos for our uninteresting objects
|
||||
int ocount = (_model.objectTileIds == null) ? 0 :
|
||||
_model.objectTileIds.length;
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
_objects.add(createObjectInfo(_model.objectTileIds[ii],
|
||||
_model.objectXs[ii],
|
||||
_model.objectYs[ii]));
|
||||
}
|
||||
|
||||
// create display object infos for our interesting objects
|
||||
for (int ii = 0, ll = _model.objectInfo.length; ii < ll; ii++) {
|
||||
_objects.add(createObjectInfo(_model.objectInfo[ii]));
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getBaseTileId (int x, int y)
|
||||
{
|
||||
return _model.getBaseTile(x, y);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void getObjects (Rectangle region, ObjectSet set)
|
||||
{
|
||||
for (int ii = 0, ll = _objects.size(); ii < ll; ii++) {
|
||||
ObjectInfo info = (ObjectInfo)_objects.get(ii);
|
||||
if (region.contains(info.x, info.y)) {
|
||||
set.insert(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setBaseTile (int fqTileId, int x, int y)
|
||||
{
|
||||
_model.setBaseTile(x, y, fqTileId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setBaseTiles (Rectangle r, int setId, int setSize)
|
||||
{
|
||||
for (int x = r.x; x < r.x + r.width; x++) {
|
||||
for (int y = r.y; y < r.y + r.height; y++) {
|
||||
int index = _rando.nextInt(setSize);
|
||||
setBaseTile(TileUtil.getFQTileId(setId, index), x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public ObjectInfo addObject (int fqTileId, int x, int y)
|
||||
{
|
||||
ObjectInfo info = createObjectInfo(fqTileId, x, y);
|
||||
_model.addObject(info);
|
||||
_objects.add(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean removeObject (ObjectInfo info)
|
||||
{
|
||||
_model.removeObject(info);
|
||||
return _objects.remove(info);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public MisoSceneModel getSceneModel ()
|
||||
{
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this Miso scene object.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An extensible {@link #toString()} helper.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("width=").append(_model.width);
|
||||
buf.append(", height=").append(_model.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link ObjectInfo} record from the supplied tile
|
||||
* information.
|
||||
*/
|
||||
protected ObjectInfo createObjectInfo (int tileId, int x, int y)
|
||||
{
|
||||
return new ObjectInfo(tileId, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link ObjectInfo} record from the supplied source
|
||||
* record.
|
||||
*/
|
||||
protected ObjectInfo createObjectInfo (ObjectInfo source)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/** The miso scene model from which we obtain our data. */
|
||||
protected SimpleMisoSceneModel _model;
|
||||
|
||||
/** The scene object records. */
|
||||
protected ArrayList _objects = new ArrayList();
|
||||
|
||||
/** A random number generator for filling random base tiles. */
|
||||
protected Random _rando = new Random();
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
//
|
||||
// $Id: SimpleMisoSceneModel.java,v 1.1 2003/02/12 05:39:15 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
/**
|
||||
* Contains miso scene data for a scene that is assumed to be reasonably
|
||||
* simple and small, such that all base tile data for the entire scene can
|
||||
* be stored in a single contiguous array.
|
||||
*
|
||||
* <p> Additionally, it makes the assumption that the single model will be
|
||||
* used to display a scene on a rectangular screen (dimensions defined by
|
||||
* {@link #vwidth} and {@link #vheight}) and further optimizes the base
|
||||
* tile array to obviate the need to store tile data for things that fall
|
||||
* outside the bounds of the screen.
|
||||
*/
|
||||
public class SimpleMisoSceneModel extends MisoSceneModel
|
||||
{
|
||||
/** The viewport width in tiles. */
|
||||
public int vwidth;
|
||||
|
||||
/** The viewport height in tiles. */
|
||||
public int vheight;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) in compressed
|
||||
* format. Don't go poking around in here, use the accessor
|
||||
* methods. */
|
||||
public int[] baseTileIds;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) of the
|
||||
* "uninteresting" tiles in the object layer. */
|
||||
public int[] objectTileIds;
|
||||
|
||||
/** The x coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectXs;
|
||||
|
||||
/** The y coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectYs;
|
||||
|
||||
/** Information records for the "interesting" objects in the object
|
||||
* layer. */
|
||||
public ObjectInfo[] objectInfo;
|
||||
|
||||
/**
|
||||
* Creates a completely uninitialized model suitable for little more
|
||||
* than unserialization.
|
||||
*/
|
||||
public SimpleMisoSceneModel ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a blank scene model with the specified dimensions.
|
||||
*/
|
||||
public SimpleMisoSceneModel (int width, int height, int vwidth, int vheight)
|
||||
{
|
||||
super(width, height);
|
||||
this.vwidth = vwidth;
|
||||
this.vheight = vheight;
|
||||
allocateBaseTileArray();
|
||||
|
||||
// start with zero-length object arrays
|
||||
objectTileIds = new int[0];
|
||||
objectXs = new short[0];
|
||||
objectYs = new short[0];
|
||||
objectInfo = new ObjectInfo[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fully-qualified tile id of the base tile at the specified
|
||||
* row and column.
|
||||
*/
|
||||
public int getBaseTile (int col, int row)
|
||||
{
|
||||
int index = getIndex(col, row);
|
||||
return (index == -1) ? 0 : baseTileIds[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fully-qualified tile id of a base tile.
|
||||
*
|
||||
* @return false if the specified tile coordinates are outside
|
||||
* of the viewport and the tile was not saved.
|
||||
*/
|
||||
public boolean setBaseTile (int col, int row, int fqBaseTileId)
|
||||
{
|
||||
int index = getIndex(col, row);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
baseTileIds[index] = fqBaseTileId;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to this model.
|
||||
*/
|
||||
public void addObject (ObjectInfo info)
|
||||
{
|
||||
if (info.isInteresting()) {
|
||||
objectInfo = (ObjectInfo[])ArrayUtil.append(objectInfo, info);
|
||||
} else {
|
||||
objectTileIds = ArrayUtil.append(objectTileIds, info.tileId);
|
||||
objectXs = ArrayUtil.append(objectXs, (short)info.x);
|
||||
objectYs = ArrayUtil.append(objectYs, (short)info.y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an object from this model.
|
||||
*/
|
||||
public void removeObject (ObjectInfo info)
|
||||
{
|
||||
// look for it in the interesting info array
|
||||
int oidx = ListUtil.indexOfEqual(objectInfo, info);
|
||||
if (oidx != -1) {
|
||||
objectInfo = (ObjectInfo[])ArrayUtil.splice(objectInfo, oidx, 1);
|
||||
}
|
||||
|
||||
// look for it in the uninteresting arrays
|
||||
oidx = IntListUtil.indexOf(objectTileIds, info.tileId);
|
||||
if (oidx != -1) {
|
||||
objectTileIds = ArrayUtil.splice(objectTileIds, oidx, 1);
|
||||
objectXs = ArrayUtil.splice(objectXs, oidx, 1);
|
||||
objectYs = ArrayUtil.splice(objectYs, oidx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index into the baseTileIds[] for the specified
|
||||
* x and y coordinates, or return -1 if the specified coordinates
|
||||
* are outside of the viewable area.
|
||||
*
|
||||
* Assumption: The viewable area is centered and aligned as far
|
||||
* to the top of the isometric scene as possible, such that
|
||||
* the upper-left corner is at the point where the tiles
|
||||
* (0, vwid) and (0, vwid-1) touch. The upper-right corner
|
||||
* is at the point where the tiles (vwid-1, 0) and (vwid, 0)
|
||||
* touch.
|
||||
*
|
||||
* The viewable area is made up of "fat" rows and "thin" rows. The
|
||||
* fat rows display one more tile than the thin rows because their
|
||||
* first and last tiles are halfway off the viewable area. The thin
|
||||
* rows are fully contained within the viewable area except for the
|
||||
* first and last thin rows, which display only their bottom and top
|
||||
* halves, respectively. Note that #fatrows == #thinrows - 1;
|
||||
*/
|
||||
protected int getIndex (int x, int y)
|
||||
{
|
||||
// check to see if the index lies in one of the "fat" rows
|
||||
if (((x + y) & 1) == (vwidth & 1)) {
|
||||
|
||||
int col = (vwidth + x - y) >> 1;
|
||||
int row = x - col;
|
||||
if ((col < 0) || (col > vwidth) ||
|
||||
(row < 0) || (row >= vheight)) {
|
||||
return -1; // out of view
|
||||
}
|
||||
|
||||
return (vwidth + 1) * row + col;
|
||||
|
||||
} else {
|
||||
// the index must be in a "thin" row
|
||||
int col = (vwidth + x - y - 1) >> 1;
|
||||
int row = x - col;
|
||||
if ((col < 0) || (col >= vwidth) ||
|
||||
(row < 0) || (row > vheight)) {
|
||||
return -1; // out of view
|
||||
}
|
||||
|
||||
// we store the all the fat rows first, then all the thin
|
||||
// rows, the '(vwidth + 1) * vheight' is the size of all
|
||||
// the fat rows.
|
||||
return row * vwidth + col + (vwidth + 1) * vheight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the base tile array.
|
||||
*/
|
||||
protected void allocateBaseTileArray ()
|
||||
{
|
||||
baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
{
|
||||
SimpleMisoSceneModel model = (SimpleMisoSceneModel)super.clone();
|
||||
model.baseTileIds = (int[])baseTileIds.clone();
|
||||
model.objectTileIds = (int[])objectTileIds.clone();
|
||||
model.objectXs = (short[])objectXs.clone();
|
||||
model.objectYs = (short[])objectYs.clone();
|
||||
model.objectInfo = (ObjectInfo[])objectInfo.clone();
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the interesting and uninteresting parts of a miso scene
|
||||
* model given lists of {@link ObjectInfo} records for each.
|
||||
*/
|
||||
public static void populateObjects (SimpleMisoSceneModel model,
|
||||
ArrayList ilist, ArrayList ulist)
|
||||
{
|
||||
// set up the uninteresting arrays
|
||||
int ucount = ulist.size();
|
||||
model.objectTileIds = new int[ucount];
|
||||
model.objectXs = new short[ucount];
|
||||
model.objectYs = new short[ucount];
|
||||
for (int ii = 0; ii < ucount; ii++) {
|
||||
ObjectInfo info = (ObjectInfo)ulist.get(ii);
|
||||
model.objectTileIds[ii] = info.tileId;
|
||||
model.objectXs[ii] = (short)info.x;
|
||||
model.objectYs[ii] = (short)info.y;
|
||||
}
|
||||
|
||||
// set up the interesting array
|
||||
int icount = ilist.size();
|
||||
model.objectInfo = new ObjectInfo[icount];
|
||||
ilist.toArray(model.objectInfo);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user