Path finder mob not working(reward)

My star mob is hardly moving it only moves sometimes by little here are the codes.Who helps me fix this will get free steam game copy.Here are some classes that are connected to the mob.
Star


package com.kiko.quest.entity.mob;

import java.util.List;

import com.kiko.quest.graphics.AnimatedSprite;
import com.kiko.quest.graphics.Screen;
import com.kiko.quest.graphics.Sprite;
import com.kiko.quest.graphics.SpriteSheet;
import com.kiko.quest.level.Node;
import com.kiko.quest.util.Vector2i;

public class Star extends Mob {
	private AnimatedSprite down = new AnimatedSprite(SpriteSheet.dummy_down, 32, 32, 3);
	private AnimatedSprite up = new AnimatedSprite(SpriteSheet.dummy_up, 32, 32, 3);
	private AnimatedSprite left = new AnimatedSprite(SpriteSheet.dummy_left, 32, 32, 3);
	private AnimatedSprite right = new AnimatedSprite(SpriteSheet.dummy_right, 32, 32, 3);

	private AnimatedSprite animSprite = down;

	private int xa = 0;
	private int ya = 0;
	private List<Node> path = null;
	private int time = 0;

	public Star(int x, int y) {
		this.x = x << 4;
		this.y = y << 4;
		sprite = Sprite.dummy;
	}

	private void move() {

		xa = 0;
		ya = 0;
		int px = level.getPlayerAt(0).getX();
		int py = level.getPlayerAt(0).getY();
		Vector2i start = new Vector2i(getX() >> 4, getY() >> 4);
		Vector2i destination = new Vector2i(px >> 4, py >> 4);
		if (time % 3 == 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++;
				if (x > vec.getX() << 4)
					xa--;
				if (y < vec.getY() << 4)
					ya++;
				if (y > vec.getY() << 4)
					ya--;
			}
		}
		if (xa != 0 || ya != 0) {
			move(xa, ya);
			walking = true;
		} else
			walking = false;

	}

	public void update() {
		move();
		if (walking)
			animSprite.update();
		else
			animSprite.setFrame(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();
		screen.renderMob(x - 16, y - 16, this);
	}
}


Entity


import java.util.Random;

import com.kiko.quest.graphics.Screen;
import com.kiko.quest.graphics.Sprite;
import com.kiko.quest.level.Level;

public class Entity {

	protected int x, y;
	protected Sprite sprite;
	private boolean removed = false;
	protected Level level;
	protected final Random random = new Random();

	public Entity() {

	}

	public Entity(int x, int y, Sprite sprite) {
		this.x = x;
		this.y = y;
		this.sprite = sprite;
	}

	public void update() {
	}

	public void render(Screen screen) {
		if (sprite != null)
			screen.renderSprite((int) x, (int) y, sprite, true);

	}

	public void remove() {
		// Remove from level
		removed = true;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public Sprite getSprite() {
		return sprite;
	}

	public boolean isRemoved() {
		return removed;
	}

	public void init(Level level) {
		this.level = level;
	}
}


Level


package com.kiko.quest.level;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.kiko.quest.entity.Entity;
import com.kiko.quest.entity.mob.Player;
import com.kiko.quest.entity.particle.Particle;
import com.kiko.quest.entity.projectile.Projectile;
import com.kiko.quest.graphics.Screen;
import com.kiko.quest.level.tile.Tile;
import com.kiko.quest.util.Vector2i;

public class Level {

	protected int width, height;
	protected int[] tilesInt;
	protected int[] tiles;

	private List<Entity> entities = new ArrayList<Entity>();
	private List<Projectile> projectiles = new ArrayList<Projectile>();
	private List<Particle> particles = new ArrayList<Particle>();

	private List<Player> players = new ArrayList<Player>();

	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 static Level spawn = new SpawnLevel("/levels/spawn.png");

	public Level(int width, int height) {
		this.width = width;
		this.height = height;
		tilesInt = new int[width * height];
		generateLevel();
	}

	public Level(String path) {
		loadLevel(path);
		generateLevel();

	}

	protected void generateLevel() {

	}

	protected void loadLevel(String path) {

	}

	public void update() {
		Tile.water.ChangeW();
		for (int i = 0; i < entities.size(); i++) {
			entities.get(i).update();
		}
		for (int i = 0; i < projectiles.size(); i++) {
			projectiles.get(i).update();
		}
		for (int i = 0; i < particles.size(); i++) {
			particles.get(i).update();
		}
		for (int i = 0; i < players.size(); i++) {
			players.get(i).update();
		}
		remove();
	}

	private void remove() {
		for (int i = 0; i < entities.size(); i++) {
			if (entities.get(i).isRemoved())
				entities.remove(i);
		}
		for (int i = 0; i < projectiles.size(); i++) {
			if (projectiles.get(i).isRemoved())
				projectiles.remove(i);
		}
		for (int i = 0; i < particles.size(); i++) {
			if (particles.get(i).isRemoved())
				particles.remove(i);
		}
		for (int i = 0; i < players.size(); i++) {
			if (players.get(i).isRemoved())
				players.remove(i);
		}

	}

	public List<Projectile> getProjectiles() {
		return projectiles;
	}

	private void time() {

	}

	public boolean tilecollision(int x, int y, int size, int xOffset, int yOffset) {
		boolean solid = false;
		for (int c = 0; c < 4; c++) {
			int xt = (x - c % 2 * size + xOffset) >> 4; // Sprite collision fix
			int yt = (y - c / 2 * size + yOffset) >> 4;
			if (getTile(xt, yt).solid())
				solid = true;
		}
		return solid;
	}

	public void render(int xScroll, int yScroll, Screen screen) {
		screen.setOffset(xScroll, yScroll);
		int x0 = xScroll >> 4;
		int x1 = (xScroll + screen.width + 16) >> 4;
		int y0 = yScroll >> 4;
		int y1 = (yScroll + screen.height + 16) >> 4;

		for (int y = y0; y < y1; y++) {
			for (int x = x0; x < x1; x++) {
				getTile(x, y).render(x, y, screen);

			}
		}
		for (int i = 0; i < entities.size(); i++) {
			entities.get(i).render(screen);
		}
		for (int i = 0; i < projectiles.size(); i++) {
			projectiles.get(i).render(screen);
		}
		for (int i = 0; i < particles.size(); i++) {
			particles.get(i).render(screen);
		}
		for (int i = 0; i < players.size(); i++) {
			players.get(i).render(screen);
		}
	}

	public void add(Entity e) {
		e.init(this);
		if (e instanceof Particle) {
			particles.add((Particle) e);
		} else if (e instanceof Projectile) {
			projectiles.add((Projectile) e);
		} else if (e instanceof Player) {
			players.add((Player) e);
		} else {
			entities.add(e);
		}
	}

	public List<Player> getPlayers() {
		return players;
	}

	public Player getPlayerAt(int index) {
		return players.get(index);
	}

	public Player getClientPlayer() {
		return players.get(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;
	}

	private boolean vecInList(List<Node> list, Vector2i vector) {
		for (Node n : list) {
			if (n.tile.equals(vector))
				return true;
		}
		return false;
	}

	private double getDistance(Vector2i tile, Vector2i goal) {
		double dx = tile.getX() - goal.getX();
		double dy = tile.getY() - goal.getY();
		return Math.sqrt(dx * dx + dy * dy);
	}

	public List<Entity> getEntities(Entity e, int radius) {
		List<Entity> result = new ArrayList<Entity>();
		int ex = e.getX();
		int ey = e.getY();
		for (int i = 0; i < entities.size(); i++) {
			Entity entity = entities.get(i);
			int x = entity.getX();
			int y = entity.getY();
			int dx = Math.abs(x - ex);
			int dy = Math.abs(y - ey);
			double distance = Math.sqrt((dx * dx) + (dy * dy));
			if (distance <= radius)
				result.add(entity);
		}
		return result;
	}

	public List<Player> getPlayers(Entity e, int radius) {
		List<Player> result = new ArrayList<Player>();
		int ex = e.getX();
		int ey = e.getY();
		for (int i = 0; i < players.size(); i++) {
			Player player = players.get(i);
			int x = player.getX();
			int y = player.getY();
			int dx = Math.abs(x - ex);
			int dy = Math.abs(y - ey);
			double distance = Math.sqrt((dx * dx) + (dy * dy));
			if (distance <= radius)
				result.add(player);
		}
		return result;
	}

	// Grass = 0xFF00FF00
	// Flower = 0xFFFFFF00
	// Rock = 0xFF7F7F00
	public Tile getTile(int x, int y) {

		if (x < 0 || y < 0 || x >= width || y >= height)
			return Tile.voidTile;
		if (tiles[x + y * width] == 0xFF00FF00)
			return Tile.grass;
		if (tiles[x + y * width] == 0xFFFFFF00)
			return Tile.flower;
		if (tiles[x + y * width] == 0xFF7F7F00)
			return Tile.rock;
		if (tiles[x + y * width] == 0xFF0094FF)
			return Tile.water;
		if (tiles[x + y * width] == 0xFF808080)
			return Tile.wall;
		if (tiles[x + y * width] == 0xFF8E3F15)
			return Tile.floor;
		return Tile.voidTile;

	}
}


Node


package com.kiko.quest.level;

import com.kiko.quest.util.Vector2i;

public class Node {

	public Vector2i tile;
	public Node parent;
	public double fCost, gCost, hCost;

	public Node(Vector2i tile, Node parent, double gCost, double hCost) {
		this.tile = tile;
		this.parent = parent;
		this.gCost = gCost;
		this.hCost = hCost;
		this.fCost = this.gCost + this.hCost;
	}

}


Entity


import java.util.Random;

import com.kiko.quest.graphics.Screen;
import com.kiko.quest.graphics.Sprite;
import com.kiko.quest.level.Level;

public class Entity {

	protected int x, y;
	protected Sprite sprite;
	private boolean removed = false;
	protected Level level;
	protected final Random random = new Random();

	public Entity() {

	}

	public Entity(int x, int y, Sprite sprite) {
		this.x = x;
		this.y = y;
		this.sprite = sprite;
	}

	public void update() {
	}

	public void render(Screen screen) {
		if (sprite != null)
			screen.renderSprite((int) x, (int) y, sprite, true);

	}

	public void remove() {
		// Remove from level
		removed = true;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public Sprite getSprite() {
		return sprite;
	}

	public boolean isRemoved() {
		return removed;
	}

	public void init(Level level) {
		this.level = level;
	}
}


Level


package com.kiko.quest.level;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.kiko.quest.entity.Entity;
import com.kiko.quest.entity.mob.Player;
import com.kiko.quest.entity.particle.Particle;
import com.kiko.quest.entity.projectile.Projectile;
import com.kiko.quest.graphics.Screen;
import com.kiko.quest.level.tile.Tile;
import com.kiko.quest.util.Vector2i;

public class Level {

	protected int width, height;
	protected int[] tilesInt;
	protected int[] tiles;

	private List<Entity> entities = new ArrayList<Entity>();
	private List<Projectile> projectiles = new ArrayList<Projectile>();
	private List<Particle> particles = new ArrayList<Particle>();

	private List<Player> players = new ArrayList<Player>();

	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 static Level spawn = new SpawnLevel("/levels/spawn.png");

	public Level(int width, int height) {
		this.width = width;
		this.height = height;
		tilesInt = new int[width * height];
		generateLevel();
	}

	public Level(String path) {
		loadLevel(path);
		generateLevel();

	}

	protected void generateLevel() {

	}

	protected void loadLevel(String path) {

	}

	public void update() {
		Tile.water.ChangeW();
		for (int i = 0; i < entities.size(); i++) {
			entities.get(i).update();
		}
		for (int i = 0; i < projectiles.size(); i++) {
			projectiles.get(i).update();
		}
		for (int i = 0; i < particles.size(); i++) {
			particles.get(i).update();
		}
		for (int i = 0; i < players.size(); i++) {
			players.get(i).update();
		}
		remove();
	}

	private void remove() {
		for (int i = 0; i < entities.size(); i++) {
			if (entities.get(i).isRemoved())
				entities.remove(i);
		}
		for (int i = 0; i < projectiles.size(); i++) {
			if (projectiles.get(i).isRemoved())
				projectiles.remove(i);
		}
		for (int i = 0; i < particles.size(); i++) {
			if (particles.get(i).isRemoved())
				particles.remove(i);
		}
		for (int i = 0; i < players.size(); i++) {
			if (players.get(i).isRemoved())
				players.remove(i);
		}

	}

	public List<Projectile> getProjectiles() {
		return projectiles;
	}

	private void time() {

	}

	public boolean tilecollision(int x, int y, int size, int xOffset, int yOffset) {
		boolean solid = false;
		for (int c = 0; c < 4; c++) {
			int xt = (x - c % 2 * size + xOffset) >> 4; // Sprite collision fix
			int yt = (y - c / 2 * size + yOffset) >> 4;
			if (getTile(xt, yt).solid())
				solid = true;
		}
		return solid;
	}

	public void render(int xScroll, int yScroll, Screen screen) {
		screen.setOffset(xScroll, yScroll);
		int x0 = xScroll >> 4;
		int x1 = (xScroll + screen.width + 16) >> 4;
		int y0 = yScroll >> 4;
		int y1 = (yScroll + screen.height + 16) >> 4;

		for (int y = y0; y < y1; y++) {
			for (int x = x0; x < x1; x++) {
				getTile(x, y).render(x, y, screen);

			}
		}
		for (int i = 0; i < entities.size(); i++) {
			entities.get(i).render(screen);
		}
		for (int i = 0; i < projectiles.size(); i++) {
			projectiles.get(i).render(screen);
		}
		for (int i = 0; i < particles.size(); i++) {
			particles.get(i).render(screen);
		}
		for (int i = 0; i < players.size(); i++) {
			players.get(i).render(screen);
		}
	}

	public void add(Entity e) {
		e.init(this);
		if (e instanceof Particle) {
			particles.add((Particle) e);
		} else if (e instanceof Projectile) {
			projectiles.add((Projectile) e);
		} else if (e instanceof Player) {
			players.add((Player) e);
		} else {
			entities.add(e);
		}
	}

	public List<Player> getPlayers() {
		return players;
	}

	public Player getPlayerAt(int index) {
		return players.get(index);
	}

	public Player getClientPlayer() {
		return players.get(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;
	}

	private boolean vecInList(List<Node> list, Vector2i vector) {
		for (Node n : list) {
			if (n.tile.equals(vector))
				return true;
		}
		return false;
	}

	private double getDistance(Vector2i tile, Vector2i goal) {
		double dx = tile.getX() - goal.getX();
		double dy = tile.getY() - goal.getY();
		return Math.sqrt(dx * dx + dy * dy);
	}

	public List<Entity> getEntities(Entity e, int radius) {
		List<Entity> result = new ArrayList<Entity>();
		int ex = e.getX();
		int ey = e.getY();
		for (int i = 0; i < entities.size(); i++) {
			Entity entity = entities.get(i);
			int x = entity.getX();
			int y = entity.getY();
			int dx = Math.abs(x - ex);
			int dy = Math.abs(y - ey);
			double distance = Math.sqrt((dx * dx) + (dy * dy));
			if (distance <= radius)
				result.add(entity);
		}
		return result;
	}

	public List<Player> getPlayers(Entity e, int radius) {
		List<Player> result = new ArrayList<Player>();
		int ex = e.getX();
		int ey = e.getY();
		for (int i = 0; i < players.size(); i++) {
			Player player = players.get(i);
			int x = player.getX();
			int y = player.getY();
			int dx = Math.abs(x - ex);
			int dy = Math.abs(y - ey);
			double distance = Math.sqrt((dx * dx) + (dy * dy));
			if (distance <= radius)
				result.add(player);
		}
		return result;
	}

	// Grass = 0xFF00FF00
	// Flower = 0xFFFFFF00
	// Rock = 0xFF7F7F00
	public Tile getTile(int x, int y) {

		if (x < 0 || y < 0 || x >= width || y >= height)
			return Tile.voidTile;
		if (tiles[x + y * width] == 0xFF00FF00)
			return Tile.grass;
		if (tiles[x + y * width] == 0xFFFFFF00)
			return Tile.flower;
		if (tiles[x + y * width] == 0xFF7F7F00)
			return Tile.rock;
		if (tiles[x + y * width] == 0xFF0094FF)
			return Tile.water;
		if (tiles[x + y * width] == 0xFF808080)
			return Tile.wall;
		if (tiles[x + y * width] == 0xFF8E3F15)
			return Tile.floor;
		return Tile.voidTile;

	}
}


Node


package com.kiko.quest.level;

import com.kiko.quest.util.Vector2i;

public class Node {

	public Vector2i tile;
	public Node parent;
	public double fCost, gCost, hCost;

	public Node(Vector2i tile, Node parent, double gCost, double hCost) {
		this.tile = tile;
		this.parent = parent;
		this.gCost = gCost;
		this.hCost = hCost;
		this.fCost = this.gCost + this.hCost;
	}

}


Mob


package com.kiko.quest.entity.mob;

import com.kiko.quest.entity.Entity;
import com.kiko.quest.entity.projectile.Projectile;
import com.kiko.quest.entity.projectile.WizardProjectile;
import com.kiko.quest.graphics.Screen;

public abstract class Mob extends Entity {

	protected boolean moving = false;
	protected boolean walking = false;

	protected enum Direction {
		UP, DOWN, LEFT, RIGHT
	}

	protected Direction dir;

	public void move(double xa, double ya) {
		if (xa != 0 && ya != 0) {
			move(xa, 0);
			move(0, ya);
			return;
		}

		if (xa > 0)
			dir = Direction.RIGHT;
		if (xa < 0)
			dir = Direction.LEFT;
		if (ya > 0)
			dir = Direction.DOWN;
		if (ya < 0)
			dir = Direction.UP;
		for (int x = 0; x < Math.abs(xa); x++) {
			if (!collision(abs(xa), ya)) {
				this.x += abs(xa);
			}
		}
		for (int y = 0; y < Math.abs(ya); y++) {
			if (!collision(xa, abs(ya))) {
				this.y += abs(ya);
			}
		}

		/*
		 * while (xa != 0) { if (Math.abs(xa) > 1) { if (!collision(abs(xa),
		 * ya)) { this.x += abs(xa); } xa -= abs(xa); } else { if
		 * (!collision(abs(xa), ya)) { this.x += xa; } xa = 0; } } while (ya !=
		 * 0) { if (Math.abs(ya) > 1) { if (!collision(xa, abs(ya))) { this.y +=
		 * abs(ya); } ya -= abs(ya); } else { if (!collision(xa, abs(ya))) {
		 * this.y += ya; } ya = 0; } }
		 */
		// ima greska nekade

	}

	private int abs(double value) {
		if (value < 0)
			return -1;
		return 1;
	}

	public abstract void update();

	public abstract void render(Screen screen);

	protected void shoot(double x, double y, double dir) {
		// dir *= 180 / Math.PI;
		Projectile p = new WizardProjectile(x, y, dir);
		level.add(p);
	}

	private boolean collision(double xa, double ya) {
		boolean solid = false;
		for (int c = 0; c < 4; c++) {
			double xt = ((x + xa) - c % 2 * 15) / 16; // Sprite collision fix
			double yt = ((y + ya) - c / 2 * 15) / 16;
			int ix = (int) Math.ceil(xt);
			int iy = (int) Math.ceil(yt);
			if (c % 2 == 0)
				ix = (int) Math.floor(xt);
			if (c / 2 == 0)
				iy = (int) Math.floor(yt);
			if (level.getTile(ix, iy).solid())
				solid = true;
		}
		return solid;
	}

}


Vector2i


package com.kiko.quest.util;

public class Vector2i {

	private int x, y;

	public Vector2i() {
		set(0, 0);
	}

	public Vector2i(Vector2i vector) {
		set(vector.x, vector.y);
	}

	public Vector2i(int x, int y) {
		set(x, y);
	}

	public void set(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public Vector2i add(Vector2i vector) {
		this.x += vector.x;
		this.y += vector.y;
		return this;
	}

	public Vector2i subtract(Vector2i vector) {
		this.x += vector.x;
		this.y += vector.y;
		return this;
	}

	public Vector2i setX(int x) {
		this.x = x;
		return this;
	}

	public Vector2i setY(int y) {
		this.y = y;
		return this;
	}

	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;
		return false;
	}
}


SpawnLevel


package com.kiko.quest.level;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.kiko.quest.entity.mob.Chaser;
import com.kiko.quest.entity.mob.Dummy;
import com.kiko.quest.entity.mob.Star;

public class SpawnLevel extends Level {

	public SpawnLevel(String path) {
		super(path);
	}

	protected void loadLevel(String path) {
		try {
			BufferedImage image = ImageIO.read(SpawnLevel.class.getResource(path));
			int w = width = image.getWidth();
			int h = height = image.getHeight();
			tiles = new int[w * h];
			image.getRGB(0, 0, w, h, tiles, 0, w);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Exception! Could not level file!");
		}
		for (int i = 0; i < 5; i++) {
			add(new Dummy(20, 55));
		}
		add(new Star(17, 35));
		add(new Chaser(15, 55));
	}

	// Grass = 0xFF00FF00
	// Flower = 0xFFFFFF00
	// Rock = 0xFF7F7F00
	protected void generateLevel() {
	}

}

Firstly people are happy to help for free, second, the forum has a pastebin built in for a reason. Please post code that is necessary, we are not debugging your entire game!

Lol, my player class has almost 1k lines of code :smiley: I think I need to install some plugin to check my lines of code count :smiley:

@kikoano
Can you please delete the duplicating code? There are 2 places where you put level class and some more repetition maybe.

Ok now to the problem… I will modify this message.

  • When you calculate the distance, you don’t have to find real distance. (x1-x0) + (y1-y0) is enough for distance calculation. It doesn’t have to be shortest distance.
  • Don’t sort open list every time you want to check which one has lowest cost. It would be much faster to go through all of the nodes 1 by 1 and check which one is lowest.
  • I hope vec2.equals(vec2) actually works…
  • Don’t clear the lists after you are done calculating the path… Java can probably do it more efficient if you just leave it as it is…
  • Why is there i<9 for loop if at the start of the loop it says i<4 continue ?? I’m guessing that 9 was supposed to be the nearby tiles of center tile, but there are actually 8, not 9 directions (up-left, up, up-right, right, down-right, down, down-left, left) After that you do %3, since you meant 9, but because you actually implementing 4, should be %2

It is really hard to understand your code… It is very very abstracted… It seems that your A* was taken from some advanced tutorial which was opted for performance, not beginners.
Here is a great beginner tutorial that should get you to implement A* pretty easily.
http://www.policyalmanac.org/games/aStarTutorial.htm

Here is my implementation of it… Though it is kinda bound to other classes, so you cannot use it for your project… It might give you some ideas for debugging your code hopefully.


public class PathFinding {

	
	private static List<Node> open = new ArrayList<Node>();
	private static List<Node> closed = new ArrayList<Node>();
	private static int x0, y0, x1, y1;
	private static Level level;
	private static boolean pathFound = false;

	public static int[] path(Level level, int x0, int y0, int x1, int y1) {

		if (!level.canMovePathFinding((x0 << 4) + 8, (y0 << 4) + 8, x0, y0, x1, y1) || !level.canMovePathFinding((x1 << 4) + 8, (y1 << 4) + 8, x0, y0, x1, y1)) {
			System.out.println("FUCKING DOUCHE! :D");
			return new int[] {};
		}

		PathFinding.level = level;
		PathFinding.x0 = x0;
		PathFinding.y0 = y0;
		PathFinding.x1 = x1;
		PathFinding.y1 = y1;
		open.clear();
		closed.clear();

		open.add(new Node(x0, y0, null, 0, calcH(x0, y0)));

		
		int counter = 0;
		while (!pathFound) {
			if(counter >= 1500) return new int[] {};
			explore();
			counter++;
		}

		pathFound = false;

		List<Node> path = new ArrayList<Node>();

		Node node = inClosed(x1, y1);

		if(node != null) {
			path.add(node);
			while ((node = node.parent) != null) {
				path.add(node);
			}
		}

		int[] tiles = new int[path.size()];

		for (int i = 0; i < tiles.length; i++) {
			Node n = path.get(tiles.length - i - 1);
			tiles[i] = n.x + n.y * level.width;
		}

		return tiles;

	}

	private static void explore() {
		Node node = open.get(0);

		for (Node n : open) {
			if (node.getF() < node.getF()) {
				node = n;
			}
		}

		open.remove(node);
		closed.add(node);
		if (node.x == x1 && node.y == y1) {
			pathFound = true;
			return;
		}

		boolean bul = level.canMovePathFinding(((node.x - 1) << 4) + 8, ((node.y - 1) << 4) + 8, x0, y0, x1, y1);
		boolean bur = level.canMovePathFinding(((node.x + 1) << 4) + 8, ((node.y - 1) << 4) + 8, x0, y0, x1, y1);
		boolean bdr = level.canMovePathFinding(((node.x + 1) << 4) + 8, ((node.y + 1) << 4) + 8, x0, y0, x1, y1);
		boolean bdl = level.canMovePathFinding(((node.x - 1) << 4) + 8, ((node.y + 1) << 4) + 8, x0, y0, x1, y1);

		boolean bu = level.canMovePathFinding(((node.x) << 4) + 8, ((node.y - 1) << 4) + 8, x0, y0, x1, y1);
		boolean br = level.canMovePathFinding(((node.x + 1) << 4) + 8, ((node.y) << 4) + 8, x0, y0, x1, y1);
		boolean bd = level.canMovePathFinding(((node.x) << 4) + 8, ((node.y + 1) << 4) + 8, x0, y0, x1, y1);
		boolean bl = level.canMovePathFinding(((node.x - 1) << 4) + 8, ((node.y) << 4) + 8, x0, y0, x1, y1);

		explore(0, -1, node, bu, 10);
		explore(+1, 0, node, br, 10);
		explore(0, +1, node, bd, 10);
		explore(-1, 0, node, bl, 10);

		explore(-1, -1, node, bul && bu && bl, 14);
		explore(+1, -1, node, bur && bu && br, 14);
		explore(+1, +1, node, bdr && bd && br, 14);
		explore(-1, +1, node, bdl && bd && bl, 14);

	}

	private static void explore(int xo, int yo, Node node, boolean move, int g) {
		if (move) {
			if (inClosed(node.x + xo, node.y + yo) == null) {

				Node n = inOpen(node.x + xo, node.y + yo);
				if (n == null) {
					open.add(new Node(node.x + xo, node.y + yo, node, node.g + g, calcH(node.x + xo, node.y + yo)));
				} else {
					if (node.g + calcG(node, n) < n.g) {
						n.parent = node;
						n.g = node.g + 10;
					}
				}

			}
		}
	}

	private static int calcG(Node n1, Node n2) {
		return calcG(n1.x, n1.y, n2.x, n2.y);
	}

	private static int calcG(int x0, int y0, int x1, int y1) {

		if (x0 == x1 && y0 == y1) {
			throw new IllegalArgumentException("points cannot be at the same place.");
		}

		int xd = x1 - x0;
		int yd = y1 - y0;

		if (xd != 0 && yd != 0) {
			return 14;
		}
		return 10;
	}

	private static Node inClosed(int x, int y) {
		for (Node node : closed) {
			if (node.x == x && node.y == y) return node;
		}
		return null;
	}

	private static Node inOpen(int x, int y) {
		for (Node node : open) {
			if (node.x == x && node.y == y) return node;
		}
		return null;
	}

	private static int calcH(int x, int y) {
		int xd = x1 - x;
		int yd = y1 - y;

		if (xd < 0) xd = -xd;
		if (yd < 0) yd = -yd;

		return xd + yd;
	}

	private static class Node {

		public int x, y;
		public Node parent = null;
		public int g, h;

		public Node(int x, int y, Node parent, int g, int h) {
			this.x = x;
			this.y = y;
			this.parent = parent;
			this.g = g;
			this.h = h;
		}

		public int getF() {
			return g + h;
		}
	}

}

Here’s my astar if we’re sharing astars. :smiley:

+1 for http://www.policyalmanac.org/games/aStarTutorial.htm

The tutorial is very well written and understandable.

I have used it for my 4X 4k game.

Not sure how much value the implementation will have for you but since people are posting them, why not add another :stuck_out_tongue:


// unit has moved to the next tile in the path
if (unitMovementNextPathTileX[i] == startX && unitMovementNextPathTileY[i] == startY)
{

	// A*
	// determine the path to the target (in reverse order)

	int targetX = (int) unitMovementTargetX[i];
	int targetY = (int) unitMovementTargetY[i];

	// unit is not on the target...
	if (!(startX == targetX && startY == targetY))
	{

		tileX = new int[PATH_FINDING_MAX_TILES];
		tileY = new int[PATH_FINDING_MAX_TILES];
		fscore = new int[PATH_FINDING_MAX_TILES];
		gscore = new int[PATH_FINDING_MAX_TILES];
		openList = new int[PATH_FINDING_MAX_TILES];
		tileParent = new int[PATH_FINDING_MAX_TILES];
		tileIsClosed = new int[MAP_SIZE][MAP_SIZE];
		currentIndex = -1;

		int openListSize = 1;
		int tileId = 1;

		tileX[0] = targetX;
		tileY[0] = targetY;
		fscore[0] = 1;
		gscore[0] = 1;

		do
		{
			int currentBestIndex = -1;
			int currentBestScore = Integer.MAX_VALUE;
			// Look for the lowest F cost square on the
			// open list
			for (int ii = 0; ii < openListSize; ii++)
			{
				if (fscore[openList[ii]] < currentBestScore)
				{
					currentBestScore = fscore[openList[ii]];
					currentBestIndex = ii;
				}
			}
			
			// no path found/exists to the target
			if (currentBestIndex == -1)
			{
				break;
			}
			currentIndex = openList[currentBestIndex];
			int currentTileX = tileX[currentIndex];
			int currentTileY = tileY[currentIndex];

			if (startX == currentTileX && startY == currentTileY)
			{
				// We have found a path!
				break;
			}

			// if not in closed list
			if (tileIsClosed[currentTileX][currentTileY] == 0)
			{
				// Switch it to the closed list.
				tileIsClosed[currentTileX][currentTileY] = 1;
				// remove from openlist
				openList[currentBestIndex] = openList[--openListSize];

				// ensure that the tile is on the same
				// region
				if (region[currentTileX][currentTileY] == regionId)
				{
					// add neigbours to the open list if
					// necessary
					for (int ii = -1; ii < 2&&tileId<PATH_FINDING_MAX_TILES; ii++)
					{
						for (int jj = -1; jj < 2&&tileId<PATH_FINDING_MAX_TILES; jj++)
						{
							int surroundingCurrentTileX = currentTileX + ii;
							int surroundingCurrentTileY = currentTileY + jj;
							if (surroundingCurrentTileX > 0 && surroundingCurrentTileX < MAP_SIZE_MINUS_ONE && surroundingCurrentTileY > 0 && surroundingCurrentTileY < MAP_SIZE_MINUS_ONE)
							{
								tileX[tileId] = surroundingCurrentTileX;
								tileY[tileId] = surroundingCurrentTileY;

								int moveCost = ((improvements[surroundingCurrentTileX][surroundingCurrentTileY]&MOUNTIAN_FLAG)>0)?4:1;
								moveCost *=((improvements[surroundingCurrentTileX][surroundingCurrentTileY]&TREE_FLAG)>0)?3:1;
								moveCost *=((improvements[surroundingCurrentTileX][surroundingCurrentTileY]&CORN_FLAG)>0)?2:1;
								moveCost = ((improvements[surroundingCurrentTileX][surroundingCurrentTileY]&RIVER_FLAG)>0)?1:moveCost;
								
								int surroundingCurrentGscore = gscore[currentIndex] + moveCost;

								gscore[tileId] = surroundingCurrentGscore;
								//TODO change Math.abs to x<0?-x:x
								fscore[tileId] = surroundingCurrentGscore + Math.abs(surroundingCurrentTileX - startX) + Math.abs(surroundingCurrentTileY - startY);
								tileParent[tileId] = currentIndex;
								openList[openListSize++] = tileId++;
							}
						}
					}
				}

			} else
			{
				// remove from openlist
				openList[currentBestIndex] = openList[--openListSize];
			}

		} while (true);

		unitMovementNextPathTileX[i] = tileX[tileParent[currentIndex]];
		unitMovementNextPathTileY[i] = tileY[tileParent[currentIndex]];
	} 

NOTE

  1. This implementation is highly computationally inefficient (it is geared for smaller class size ).
  2. path searching is done in reverse (target -> start) to determine which way a unit should travel next
  3. the path finding is run each time a unit reaches the next tile in the path.