我有这个方法:
public boolean moveTowardsPoint(Point p, double stepSize, double minDistance, ArrayList<GameBodyObject> objects, boolean shouldStepInto, AStar astar) {
ArrayList<GameBodyObject> others = (ArrayList<GameBodyObject>) objects.clone();
others.remove(this);
if(aStarPath == null || lastPointToMove == null || !lastPointToMove.isAlmostTheSame(p, 0.01)) {
try {
astar.getGrid().unsetObstacleForObject(this);
aStarPath = astar.process(this, p, objects);
Collections.reverse(aStarPath);
currentIndex = 0;
current = null;
astar.getGrid().reset();
} catch(Exception e) {
e.printStackTrace();
}
}
lastPointToMove = p.clone();
double dx = p.getX() - getPosition().getX();
double dy = p.getY() - getPosition().getY();
Point lastPosition = getPosition().clone();
boolean isClose = false;
double dist = Math.sqrt(dx * dx + dy * dy);
if (dist < Math.max(minDistance, stepSize)) {
isClose = true;
} else {
if(aStarPath.indexOf(current) >= aStarPath.size() - 1) {
if(shouldStepInto && dist <= stepSize) {
setPosition(p.clone());
}
} else if(aStarPath != null && aStarPath.size() > 0) {
if (current == null) {
currentIndex = 0;
current = aStarPath.get((int)currentIndex);
}
double mss = stepSize / current.getWidth();
Spot p2 = aStarPath.get(Math.min((int)Math.ceil(currentIndex + mss), aStarPath.size() - 1));
Spot p1 = current;
if(!p1.equals(p2)) {
Vector v = new Vector(p2.getX() - p1.getX(), p2.getY() - p1.getY()).normalize();
getPosition().moveByVector(v.mult(stepSize));
setRotation(v.getAngle());
}
currentIndex = Math.min(currentIndex + mss, aStarPath.size() - 1);
current = aStarPath.get((int)currentIndex);
}
}
return isClose;
}
这是GameBodyObject
的方法。
它应该计算A *路径并向该路径上的某个点移动,但它的移动速度比current
(currentIndex
)向前移动通过路径要慢。我在开始时有一些距离检查,但这并不重要。我将currentIndex
移动stepSize
除以grid cell size
。就我而言,它是0.6
。然后我有一个moveByVector
方法,它只是通过向量移动Point
。
如何使其同步,使其移动速度与current
(currentIndex
)一样快?它甚至可能吗?
修改
以下是我的变量定义:
private List<Spot> aStarPath = null;
private Spot current = null;
private double currentIndex = -1;
private Point lastPointToMove;
答案 0 :(得分:0)
该解决方案中存在一个错误。在对角线上currentIndex
比玩家移动的速度快。因此,您必须考虑玩家沿着该路径移动的角度。具体地说:
double coef = Math.max(Math.abs(Math.cos(angle)),Math.abs(Math.sin(angle)));
double mss = stepSize / (current.getWidth() / coef);
完整的方法现在看起来像这样,就像一个魅力:
public boolean moveTowardsPoint(Point p, double stepSize, double minDistance, ArrayList<GameBodyObject> objects, boolean shouldStepInto, AStar astar) {
ArrayList<GameBodyObject> others = (ArrayList<GameBodyObject>) objects.clone();
others.remove(this);
if(aStarPath == null || lastPointToMove == null || !lastPointToMove.isAlmostTheSame(p, 0.01)) {
try {
astar.getGrid().unsetObstacleForObject(this);
aStarPath = astar.process(this, p, objects);
Collections.reverse(aStarPath);
currentIndex = 0;
current = null;
astar.getGrid().reset();
} catch(Exception e) {
e.printStackTrace();
}
}
lastPointToMove = p.clone();
double dx = p.getX() - getPosition().getX();
double dy = p.getY() - getPosition().getY();
Point lastPosition = getPosition().clone();
boolean isClose = false;
double dist = Math.sqrt(dx * dx + dy * dy);
if (dist < Math.max(minDistance, stepSize)) {
isClose = true;
} else {
if(aStarPath.indexOf(current) >= aStarPath.size() - 1) {
if(shouldStepInto && dist <= stepSize) {
setPosition(p.clone());
}
} else if(aStarPath != null && aStarPath.size() > 0) {
if (current == null) {
currentIndex = 0;
current = aStarPath.get((int)currentIndex);
}
Spot c1 = aStarPath.get((int)currentIndex);
Spot c2 = aStarPath.get(Math.min((int)currentIndex + 1, aStarPath.size() - 1));
double angle = new Vector(c2.getX() - c1.getX(),c2.getY() - c1.getY()).getAngle();
double coef = Math.max(Math.abs(Math.cos(angle)),Math.abs(Math.sin(angle)));
double mss = stepSize / (current.getWidth() / coef);
Spot p2 = aStarPath.get(Math.min((int)Math.ceil(currentIndex + mss), aStarPath.size() - 1));
Spot p1 = current;
if(!p1.equals(p2)) {
Vector v = new Vector(p2.getX() - p1.getX(), p2.getY() - p1.getY()).normalize();
getPosition().moveByVector(v.mult(stepSize));
setRotation(v.getAngle());
}
currentIndex = Math.min(currentIndex + mss, aStarPath.size() - 1);
current = aStarPath.get((int)currentIndex);
}
}
return isClose;
}