1
Fork 0

Add A* pathing algorithm

I adapted the A* I had already implemented in a Realm of Chaos, now
adapted in Java and is used to calculate the player's path to their new
location.
This commit is contained in:
Joshua Goins 2022-04-30 19:52:28 -04:00
parent 44d62fb515
commit 970988a5eb
2 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,110 @@
package com.redstrate.watersymbol;
import com.badlogic.gdx.math.Vector2;
import java.util.ArrayList;
import java.util.List;
/*
This is a direct port of the A* pathing implementation in Realm of Chaos.
*/
public class AStar {
static class Node {
Vector2 position;
int g = 0;
int h = 0;
int f = 0;
Node parent;
}
private static final int maxOpenNodes = 200;
public static ArrayList<Vector2> path(Vector2 start, Vector2 end) {
Node startNode = new Node();
startNode.position = start;
Node endNode = new Node();
endNode.position = end;
ArrayList<Node> openList = new ArrayList<>();
openList.add(startNode);
ArrayList<Node> closedList = new ArrayList<>();
while(!openList.isEmpty() && openList.size() < maxOpenNodes) {
Node currentNode = openList.get(0);
int currentIndex = 0;
for(int i = 0; i < openList.size(); i++) {
if(openList.get(i).f < currentNode.f) {
currentNode = openList.get(i);
currentIndex = i;
}
}
openList.remove(currentIndex);
closedList.add(currentNode);
// check if we found the goal
if(currentNode.position.epsilonEquals(endNode.position)) {
ArrayList<Vector2> path = new ArrayList<>();
Node current = currentNode;
while(current != null) {
path.add(current.position);
current = current.parent;
}
System.out.println(path.toString());
return path;
}
ArrayList<Node> children = new ArrayList<>();
ArrayList<Vector2> adjacentPositions = new ArrayList<>();
adjacentPositions.add(new Vector2(0, -1));
adjacentPositions.add(new Vector2(0, 1));
adjacentPositions.add(new Vector2(-1, 0));
adjacentPositions.add(new Vector2(1, 0));
adjacentPositions.add(new Vector2(-1, -1));
adjacentPositions.add(new Vector2(-1, 1));
adjacentPositions.add(new Vector2(1, -1));
adjacentPositions.add(new Vector2(1, 1));
for (Vector2 position : adjacentPositions) {
Node newNode = new Node();
newNode.position = new Vector2(currentNode.position.x + position.x, currentNode.position.y + position.y);
newNode.parent = currentNode;
children.add(newNode);
}
for(Node child : children) {
boolean shouldContinue = false;
for(Node closedChild : closedList) {
if(child.position.epsilonEquals(closedChild.position)) {
shouldContinue = true;
}
}
if(shouldContinue)
continue;
child.g = currentNode.g + 1;
child.h = (int) (Math.pow(child.position.x - endNode.position.x, 2) + Math.pow(child.position.y - endNode.position.y, 2));
child.f = child.g + child.h;
for(Node openNode : openList) {
if(child.position.epsilonEquals(openNode.position) && child.g > openNode.g) {
shouldContinue = true;
}
}
if(shouldContinue)
continue;
openList.add(child);
}
}
return null;
}
}

View file

@ -12,9 +12,12 @@ import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.ScreenUtils;
import com.redstrate.watersymbol.AStar;
import com.redstrate.watersymbol.Player;
import com.redstrate.watersymbol.WaterSymbol;
import java.util.ArrayList;
public class GameScreen implements Screen {
private final WaterSymbol game;
private boolean hasStartedMoving = false;
@ -64,6 +67,23 @@ public class GameScreen implements Screen {
// player is trying to move
if(Gdx.input.isButtonPressed(0)) {
hasStartedMoving = true;
Vector3 mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(mousePos);
double newX = Math.floor(mousePos.x);
double newY = Math.floor(mousePos.y);
int newFixedX = (int) (newX / 32.0);
int newFixedY = (int) (newY / 32.0);
ArrayList<Vector2> path = AStar.path(new Vector2(player.positionX, player.positionY), new Vector2((float)newFixedX, (float)newFixedY));
if(path != null) {
for (Vector2 position : path) {
game.batch.draw(playerTexture, position.x * 32, position.y * 32);
}
}
} else if(hasStartedMoving) {
Vector3 mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);