Advertisement

Following an A Path

Started by June 11, 2012 07:45 PM
3 comments, last by Eliaszhou 12 years, 2 months ago
I wrote an A* pathfinder for my game but I'm unsure about the best way of having my characters maneuver along it. Any sugestions? I'm storing the path as an ArrayList of grid blocks. should I just shet my velocity in the direction of the center of the next square? I'm worried about my characters overshooting the block then running into otehr obsticles.
I would use a tolerance radius that gets bigger with a higher speed (depending on the stopping distance). When the unit is inside the circle, start moving to the next goal for a smooth move around the corner. You need to set a maximum allowed speed to prevent the circle from getting bigger than a tile.
Advertisement
The "right" solution is performing pathfinding on physically reasonable trajectories that entities can follow exactly rather than on polylines with sharp corners: for example, you can combine straight segment and circular arcs, precomputing a suitable arc to turn each corner.

Omae Wa Mou Shindeiru

Here is my butchered solution if anyone runs into the same question. I'll clean it up and repost it eventually.


public boolean followPathSimple(Entity entity,PhysicsWorld physicsWorld)
{
GameMath math = new GameMath();
boolean isFinished = false;
Body body = physicsWorld.getBodyByID(entity.getUserData().getID());
if(cellList.size()>currentTile)
{
//find the radius of the target I will be hitting (unused saved for later)
float targetRadius = math.pythag(cellDimensions.x/2,cellDimensions.y/2);
targetRadius += math.pythag(body.getLinearVelocity().x, body.getLinearVelocity().y);

//find the radius of the moveing object (unused saved for later)
float objectRadius = math.pythag(((BodyUserData)body.getUserData()).getDimensions().x,
((BodyUserData)body.getUserData()).getDimensions().y);
//the object moving
objectShape = new Circle(
(body.getWorldPoint(body.getLocalCenter()).x*GameConstants.M_TO_P)+16,
(body.getWorldPoint(body.getLocalCenter()).y*GameConstants.M_TO_P)+16,
5);
//if we are on the tile go to the next
if(targetShape.contains(objectShape.getCenterX(), objectShape.getCenterY()))
{
//if the path continues create a new target and increase our position on the path
if(currentTile<cellList.size()-1)
{

currentTile++;
targetShape = new Circle(
cellList.get(currentTile).getCenterX(),
cellList.get(currentTile).getCenterY(),10);
}
//if we are at the end of the list we have finished the path
else
{
isFinished = true;
body.setLinearVelocity(new Vec2(0,0));
}
}
else
{
int velX = 0;
int velY = 0;
//find the distance from the target in the x and y
float distanceX = targetShape.getCenterX()-objectShape.getCenterX();
float distanceY = targetShape.getCenterY()-objectShape.getCenterY();

//if the disance in the x is grater than the distance in the y move the entity along the x axis(4-way movement)
if(Math.abs(distanceX)>Math.abs(distanceY))
{
//if the distance is is less than zero then the object is to the right of the target
if(distanceX<0)
{
//move left
velX = (int) -entity.getVel_Max().x;
}
else if(distanceX>0)
{
//move right
velX = (int) entity.getVel_Max().x;
}
}
//else move it vertically
else
{
if(distanceY<0)
{
//move up
velY = (int) -entity.getVel_Max().y;
}
else if(distanceY>0)
{
//move down
velY = (int) entity.getVel_Max().y;
}
}
//set the new velocity of our object
body.setLinearVelocity(new Vec2(velX,velY));
}

}
//return whether or not we have finished walking anlong the path
return isFinished;
}


Here is how the movement ended up looking


if anyone wants the A* code aswell I'll put that up too.
see detour in recast navigation

This topic is closed to new replies.

Advertisement