proper diagonal path, no walking on walls!

bottom-bar
Ivory 2023-01-12 10:15:37 -05:00
parent 46f75fa53c
commit 60529c9552
3 changed files with 31 additions and 16 deletions

View File

@ -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;

View File

@ -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))));

View File

@ -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);
} }