proper diagonal path, no walking on walls!
parent
46f75fa53c
commit
60529c9552
|
|
@ -56,7 +56,7 @@ public class Terrain extends GameObject implements IPathable, IWorldBoundsAdapte
|
||||||
|
|
||||||
// TODO implement directionality. even the pathfinder doesnt give this info...
|
// TODO implement directionality. even the pathfinder doesnt give this info...
|
||||||
@Override
|
@Override
|
||||||
public boolean isWalkable(int x, int y, int fromX, int fromY) {
|
public boolean isWalkable(int x, int y) {
|
||||||
if(!isOutOfBounds(x, y)) {
|
if(!isOutOfBounds(x, y)) {
|
||||||
return getTile(x, y).isWalkable();
|
return getTile(x, y).isWalkable();
|
||||||
} else return false;
|
} else return false;
|
||||||
|
|
|
||||||
|
|
@ -51,17 +51,32 @@ public class AStarPathfinder implements IPathfinder, Serializable {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node[] getNeighbors(Node base, List<Node> open, List<Node> closed, int dstX, int dstY) {
|
private Node[] getPathableNodesFromNode(Node base, List<Node> open, List<Node> closed, int dstX, int dstY) {
|
||||||
Node[] neighbors = new Node[8];
|
List<Node> nodes = new ArrayList<Node>();
|
||||||
neighbors[0] = getPathfindingNode(base.x - 1, base.y - 1, open, closed, base, dstX, dstY);
|
Node north = getPathfindingNode(base.x, base.y - 1, open, closed, base, dstX, dstY);
|
||||||
neighbors[1] = getPathfindingNode(base.x, base.y - 1, open, closed, base, dstX, dstY);
|
Node east = getPathfindingNode(base.x - 1, base.y, open, closed, base, dstX, dstY);
|
||||||
neighbors[2] = getPathfindingNode(base.x + 1, base.y - 1, open, closed, base, dstX, dstY);
|
Node south = getPathfindingNode(base.x, base.y + 1, open, closed, base, dstX, dstY);
|
||||||
neighbors[3] = getPathfindingNode(base.x - 1, base.y, open, closed, base, dstX, dstY);
|
Node west = getPathfindingNode(base.x + 1, base.y, open, closed, base, dstX, dstY);
|
||||||
neighbors[4] = getPathfindingNode(base.x + 1, base.y, open, closed, base, dstX, dstY);
|
|
||||||
neighbors[5] = getPathfindingNode(base.x - 1, base.y + 1, open, closed, base, dstX, dstY);
|
boolean northWalkable = north != null && pathable.isWalkable(north.x, north.y);
|
||||||
neighbors[6] = getPathfindingNode(base.x, base.y + 1, open, closed, base, dstX, dstY);
|
boolean eastWalkable = east != null && pathable.isWalkable(east.x, east.y);
|
||||||
neighbors[7] = getPathfindingNode(base.x + 1, base.y + 1, open, closed, base, dstX, dstY);
|
boolean southWalkable = south != null && pathable.isWalkable(south.x, south.y);
|
||||||
return neighbors;
|
boolean westWalkable = west != null && pathable.isWalkable(west.x, west.y);
|
||||||
|
|
||||||
|
if(northWalkable) nodes.add(north);
|
||||||
|
if(eastWalkable) nodes.add(east);
|
||||||
|
if(southWalkable) nodes.add(south);
|
||||||
|
if(westWalkable) nodes.add(west);
|
||||||
|
|
||||||
|
if(northWalkable && eastWalkable) nodes.add(getPathfindingNode(base.x - 1, base.y - 1, open, closed, base, dstX, dstY));
|
||||||
|
if(northWalkable && westWalkable) nodes.add(getPathfindingNode(base.x + 1, base.y - 1, open, closed, base, dstX, dstY));
|
||||||
|
if(southWalkable && eastWalkable) nodes.add(getPathfindingNode(base.x - 1, base.y + 1, open, closed, base, dstX, dstY));
|
||||||
|
if(southWalkable && westWalkable) nodes.add(getPathfindingNode(base.x + 1, base.y + 1, open, closed, base, dstX, dstY));
|
||||||
|
|
||||||
|
Node[] nodes2 = new Node[nodes.size()];
|
||||||
|
nodes.toArray(nodes2);
|
||||||
|
|
||||||
|
return nodes2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getPath(int x1, int y1, int x2, int y2) {
|
public Path getPath(int x1, int y1, int x2, int y2) {
|
||||||
|
|
@ -71,7 +86,7 @@ public class AStarPathfinder implements IPathfinder, Serializable {
|
||||||
List<Node> open = new ArrayList<Node>();
|
List<Node> open = new ArrayList<Node>();
|
||||||
List<Node> closed = new ArrayList<Node>();
|
List<Node> closed = new ArrayList<Node>();
|
||||||
|
|
||||||
if(!pathable.isWalkable(x2, y2, 0, 0)) return null;
|
if(!pathable.isWalkable(x2, y2)) return null;
|
||||||
|
|
||||||
open.add(getPathfindingNode(x1, y1, open, closed, null, x2, y2));
|
open.add(getPathfindingNode(x1, y1, open, closed, null, x2, y2));
|
||||||
|
|
||||||
|
|
@ -113,12 +128,12 @@ public class AStarPathfinder implements IPathfinder, Serializable {
|
||||||
return new Path(path, current);
|
return new Path(path, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node[] neighbors = getNeighbors(current, open, closed, x2, y2);
|
Node[] neighbors = getPathableNodesFromNode(current, open, closed, x2, y2);
|
||||||
|
|
||||||
for(Node node : neighbors) {
|
for(Node node : neighbors) {
|
||||||
if(node == null) continue;
|
if(node == null) continue;
|
||||||
if(closed.contains(node)) continue;
|
if(closed.contains(node)) continue;
|
||||||
if(!pathable.isWalkable(node.x, node.y, 0, 0)) continue;
|
if(!pathable.isWalkable(node.x, node.y)) continue;
|
||||||
if(open.contains(node)) {
|
if(open.contains(node)) {
|
||||||
int newGCost = current.g + (int)(Math.round(10 * Math.sqrt(Math.pow(node.x - current.x, 2) + Math.pow(node.y - current.y, 2))));
|
int newGCost = current.g + (int)(Math.round(10 * Math.sqrt(Math.pow(node.x - current.x, 2) + Math.pow(node.y - current.y, 2))));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package xyz.valnet.hadean.pathfinding;
|
package xyz.valnet.hadean.pathfinding;
|
||||||
|
|
||||||
public interface IPathable {
|
public interface IPathable {
|
||||||
public boolean isWalkable(int x, int y, int fromX, int fromY);
|
public boolean isWalkable(int x, int y);
|
||||||
public boolean isOutOfBounds(int x, int y);
|
public boolean isOutOfBounds(int x, int y);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue