I'm developing a game in Java and i'm having issues using and implementing my A* path finding algorithm. Currently, i have entities set up so that an entity can't exist outside of a level(each entity has access to the current level). for this reason, i stored the algorithm method 'findPath' in the base Level class. Below is the algorithm code, and the movement code for the entity, which as you can see calls the find path method in level. My issue is that when I run the code, I move the player towards the entity and the entity does nothing. I've put in some debug print lines (i'll leave those in so you can see), and the list path
that is returned constantly returns just []
. I've been through everything and can;'t figure it out. Hope someone can help!
Thanks
code: in Level.java class:
private Comparator<Node> nodeSorter = new Comparator<Node>() {
public int compare(Node n0, Node n1) {
if (n1.fCost < n0.fCost) return +1;
if (n1.fCost > n0.fCost) return -1;
return 0;
}
};
public List<Node> findPath(Vector2i start, Vector2i goal) {
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Node current = new Node(start, null, 0, getDistance(start, goal));
openList.add(current);
while (openList.size() > 0) {
Collections.sort(openList, nodeSorter);
current = openList.get(0);
if (current.tile.equals(goal)) {
List<Node> path = new ArrayList<Node>();
while (current.parent != null) {
path.add(current);
current = current.parent;
}
openList.clear();
closedList.clear();
return path;
}
openList.remove(current);
closedList.add(current);
for (int i = 0; i < 9; i ++){
if (i == 4) continue;
int x = current.tile.getX();
int y = current.tile.getY();
int xi = (i % 3) - 1;
int yi = (i / 3) - 1;
Tile at = getTile(x + xi, y + yi);
if (at == null) continue;
if (at.solid()) continue;
Vector2i a = new Vector2i(x + xi, y + yi);
double gCost = current.gCost + getDistance(current.tile, a);
double hCost = getDistance(a, goal);
Node node = new Node(a, current, gCost, hCost);
if (vecInList(closedList, a) && gCost >= node.gCost) continue;
if (!vecInList(openList, a) || gCost < node.gCost) openList.add(node);
}
}
closedList.clear();
return null;
}
And in my "Wizard.java", which extends Mob, and in turn entity:
private List<Node> path = null;
public Wizard(int x, int y) {
this.x = x << 4;
this.y = y << 4;
sprite = animSprite.getSprite();
}
private void move() {
xa = 0;
ya = 0;
int px = (int)level.getPlayerAt(0).getX();
int py = (int)level.getPlayerAt(0).getY();
Vector2i start = new Vector2i((int)getX() >> 4, (int)getY() >> 4);
Vector2i destination = new Vector2i(px >> 4, py >> 4);
if (time % 60 == 0) path = level.findPath(start, destination);
if (path != null){
if (path.size() > 0){
Vector2i vec = path.get(path.size() -1).tile;
if (x < vec.getX() << 4) xa += speed;
if (x > vec.getX() << 4) xa -= speed;
if (y < vec.getY() << 4) ya += speed;
if (y > vec.getY() << 4) ya -= speed;
}
}
if (xa != 0 || ya != 0) {
move(xa, ya);
walking = true;
} else
walking = false;
}
public void update() {
time++;
if (!collision(xa, ya)){
move();
}
move();
if (walking) animSprite.update();
else
animSprite.setFrameRate(0);
if (ya < 0) {
animSprite = up;
dir = Direction.UP;
} else if (ya > 0) {
animSprite = down;
dir = Direction.DOWN;
}
if (xa < 0) {
animSprite = left;
dir = Direction.LEFT;
} else if (xa > 0) {
animSprite = right;
dir = Direction.RIGHT;
}
}
public void render(Screen screen) {
sprite = animSprite.getSprite();
if (level.getTile((int)x, (int)y).solid()){
x += 16;
y += 16;
}
screen.renderMob((int)(x - 16), (int)(y - 16), this);
}
Node equals code:
public boolean equals(Object object){
if(!(object instanceof Vector2i)) return false;
Vector2i vec = (Vector2i) object;
if (vec.getX() == this.getX() && vec.getY() == this.getY()) return true;
else return false;
}