I am currently working on implementing the A* Pathfinding algorithm into my snake game. I understand how the algorithm works, the only difficult part is implementing the algorithm. More specifically, I am trying to get the neighboring nodes to the current node on the grid. The reason why I am doing this is because I will then be able to loop through the neighboring nodes (with a list) and check which ones have the lowest g and h costs. I have created a method that loops through a list of x and y coordinates of the neighboring nodes and then I create a new temporary node that holds those coordinates. I then have a by default empty nodeNeighborList that keeps track of all the neighboring nodes. Within the method, the temporary node variable (in method) is then added to the list.
My issue is that when I call this method in the run method, I get a NullPointerException that says the issue comes from where I have added the temporary node.
I get the error at 'game.nodeNeighboursList.add(tempNeighbours);'
Here is my code -
public class Nodes {
private Game game = new Game();
public double h,f;
public int x, y;
public Vector2 vector2;
public Nodes parent;
public Nodes(Vector2 v, double h) {
this.vector2 = v;
this.h = h;
}
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return this.y;
}
public void setY(int y) {
this.y = y;
}
public int getDistanceFromTarget(int x1, int x2, int y1, int y2) {
return (int) Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
}
public Nodes getNeigbouringNodes(Nodes CurrentNode) {
int[] NeighbourX = {CurrentNode.getX()-20, CurrentNode.getX()+20, CurrentNode.getX(),
CurrentNode.getX(),CurrentNode.getX()-20, CurrentNode.getX()+20,CurrentNode.getX()-20,CurrentNode.getX()+20};
int [] NeighbourY = {CurrentNode.getY(),CurrentNode.getY(),CurrentNode.getY()+20,
CurrentNode.getY()-20,CurrentNode.getY()-20,CurrentNode.getY()-20,CurrentNode.getY()+20,CurrentNode.getY()+20};
for(int x = 0 ; x < NeighbourX.length ; x ++) {
for(int y = 0 ; y < NeighbourY.length; y++) {
Nodes tempNeighbours = new Nodes(new Vector2(NeighbourX[x],NeighbourY[y]),getDistanceFromTarget(
NeighbourX[x],Apple.x,NeighbourY[y],Apple.y));
game.nodeNeighboursList.add(tempNeighbours);
return tempNeighbours;
}
}
return null;
}
}
This is my main class, the run method is where the 'getNeibouringNodes()' is called:
private int WIDTH = 800,HEIGHT = 800;
private int nodeMax = 800;
private ArrayList<Snake>snakeList;
private ArrayList<Apple>appleList;
private ArrayList<Nodes>nodeList;
public ArrayList<Nodes>nodeNeighboursList;
//private Nodes nodes;
private Snake snake;
public Apple apple;
private Vector2 nodeVector;
private Thread thread;
static int ticks = 0;
private Random rx;
private Random ry;
private Nodes node;
private int snakeSizeStart = 5;
private int size = 20;
private final int threadSpeed = 80;
private boolean right=false,left=false,up=false,down=false;
private int applePosScalar;
private int distance;
// look this up, and sorting nodes based on fcost
private Comparator<Nodes> NodeSorter = new Comparator<Nodes>() {
@Override
public int compare(Nodes arg0, Nodes arg1) {
if(arg1.getDistanceFromTarget(arg1.getX(), Apple.x, arg1.getX(), Apple.y) <
arg0.getDistanceFromTarget(arg0.getX(), Apple.x, arg0.getY(), Apple.y)) {
return 1;
}
if(arg1.getDistanceFromTarget(arg1.getX(), Apple.x, arg1.getX(), Apple.y) >
arg0.getDistanceFromTarget(arg0.getX(), Apple.x, arg0.getY(), Apple.y)) {
return -1;
}
return 0;
}
};
public void init() {
this.resize(WIDTH,HEIGHT);
this.setFocusable(true);
this.addKeyListener(this);
rx = new Random();
ry = new Random();
applePosScalar = WIDTH/size;
nodeVector = new Vector2(20,20);
snake = new Snake(0,0,size);
apple = new Apple(rx.nextInt(applePosScalar),ry.nextInt(applePosScalar),size);
//nodes = new Nodes(0,0,0,getDistance(0, Apple.x,0,Apple.y));
node = new Nodes(nodeVector,getDistance(nodeVector.getX(), Apple.x,nodeVector.getY(),Apple.y));
nodeList = new ArrayList<Nodes>();
appleList = new ArrayList<Apple>();
snakeList = new ArrayList<Snake>();
nodeNeighboursList = new ArrayList<Nodes>();
thread = new Thread(this);
thread.start();
}
public void update(Graphics g) {
paint(g);
}
public void run() {
for(;;) {
if(snakeList.size() == 0) {
snake = new Snake(snake.x,snake.y,size);
snakeList.add(snake);
}
snake.moveSnake();
System.out.println(nodeNeighboursList.size());
if(right) {
snake.x++;
}
if(left) {
snake.x--;
}
if(down) {
snake.y--;
}
if(up) {
snake.y++;
}
if(snake.x < 0 || snake.x > 39 || snake.y < 0 || snake.y > 39) {
snakeList = null;
System.exit(0);
}
// continuously add a snake to the list
snakeList.add(new Snake(snake.x,snake.y,size));
// if the above additions are larger than the snakeSizeStart, then remove a snake object from list
//Other wise there will be an infinite snake!
if(snakeList.size() > snakeSizeStart) {
snakeList.remove(0);
}
for(int i = 1 ; i < snakeList.size() ; i++) {
if(snakeList.get(0).hitBox().intersects(snakeList.get(i).hitBox())) {
//System.out.println("sdf");
}
}
if(snake.hitBox().intersects(apple.hitBox())) {
// add to the snake size, this means that the statement above (snakeList.add(new Snake)) will add a new snake
snakeSizeStart++;
appleList.add(new Apple(rx.nextInt(applePosScalar),ry.nextInt(applePosScalar),size));
}
getDistance(snake.x,apple.getX(),snake.y,apple.getY());
node.getNeigbouringNodes(node); // this is the method that gets the neighboring nodes
System.out.println("S" + nodeNeighboursList.size());
/*
I want the method to return the amount of neighboring nodes there are to the current one
*/
this.repaint();
try {
Thread.sleep(threadSpeed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If anything is unclear, please do not hesitate to ask as I will gladly clear anything up. I would really appreciate any help I can get! Thank you!