
com.threerings.miso.client.TilePath Maven / Gradle / Ivy
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
// https://github.com/threerings/nenya
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.miso.client;
import java.util.List;
import java.awt.Point;
import com.threerings.media.sprite.Sprite;
import com.threerings.media.util.LineSegmentPath;
import com.threerings.media.util.MathUtil;
import com.threerings.miso.util.MisoSceneMetrics;
import com.threerings.miso.util.MisoUtil;
/**
* The tile path represents a path of tiles through a scene. The path is
* traversed by treating each pair of connected tiles as a line segment.
* Only ambulatory sprites can follow a tile path, and their tile
* coordinates are updated as the path is traversed.
*/
public class TilePath extends LineSegmentPath
{
/**
* Constructs a tile path.
*
* @param metrics the metrics for the scene the with which the path is
* associated.
* @param sprite the sprite to follow the path.
* @param tiles the tiles to be traversed during the path.
* @param destx the destination x-position in screen pixel
* coordinates.
* @param desty the destination y-position in screen pixel
* coordinates.
*/
public TilePath (MisoSceneMetrics metrics, Sprite sprite,
List tiles, int destx, int desty)
{
// constrain destination pixels to fine coordinates
Point fpos = new Point();
MisoUtil.screenToFull(metrics, destx, desty, fpos);
// add the starting path node
int sx = sprite.getX(), sy = sprite.getY();
Point ipos = MisoUtil.screenToTile(metrics, sx, sy, new Point());
addNode(sx, sy, NORTH);
// TODO: make more visually appealing path segments from start to
// second tile, and penultimate to ultimate tile
// add all remaining path nodes excepting the last one
Point prev = new Point(ipos.x, ipos.y);
Point spos = new Point();
int size = tiles.size();
for (int ii = 1; ii < size - 1; ii++) {
Point next = tiles.get(ii);
// determine the direction from previous to next node
int dir = MisoUtil.getIsoDirection(prev.x, prev.y, next.x, next.y);
// determine the node's position in screen pixel coordinates
MisoUtil.tileToScreen(metrics, next.x, next.y, spos);
// add the node to the path, wandering through the middle
// of each tile in the path for now
int dsx = spos.x + metrics.tilehwid;
int dsy = spos.y + metrics.tilehhei;
addNode(dsx, dsy, dir);
prev = next;
}
// get the final destination point's screen coordinates
// constrained to the closest full coordinate
MisoUtil.fullToScreen(metrics, fpos.x, fpos.y, spos);
// get the tile coordinates for the final destination tile
int tdestx = MisoUtil.fullToTile(fpos.x);
int tdesty = MisoUtil.fullToTile(fpos.y);
// get the facing direction for the final node
int dir;
if (prev.x == ipos.x && prev.y == ipos.y) {
// if destination is within starting tile, direction is
// determined by studying the fine coordinates
dir = MisoUtil.getDirection(metrics, sx, sy, spos.x, spos.y);
} else {
// else it's based on the last tile we traversed
dir = MisoUtil.getIsoDirection(prev.x, prev.y, tdestx, tdesty);
}
// add the final destination path node
addNode(spos.x, spos.y, dir);
}
/**
* Returns the estimated number of millis that we'll be traveling
* along this path.
*/
public long getEstimTravelTime ()
{
return (long)(_estimPixels / _vel);
}
@Override
public void addNode (int x, int y, int dir)
{
super.addNode(x, y, dir);
if (_last == null) {
_last = new Point();
} else {
_estimPixels += MathUtil.distance(_last.x, _last.y, x, y);
}
_last.setLocation(x, y);
}
/** Used to compute estimated travel time. */
protected Point _last;
/** Estimated pixels traveled. */
protected int _estimPixels;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy