anvaka / ngraph.path

Path finding in a graph

Home Page:https://anvaka.github.io/ngraph.path.demo/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage in a grid based system

minotaurrr opened this issue · comments

commented

Hi,

I’m developing a simple game on a 2D grid.

I have many enemies that have to find shortest path to the player every 0.5 second.
There’s static and dynamic obstacles in the grid (when an enemy or player moves, the tile it moves onto becomes an obstacle for other enemies).
In other words they can’t stand on the same tile.

I’m trying to use your library to implement this but a little confused as to how to code the obstacles bit.

Can I get some advice please? Do I have to add links to every walkable neighbour tile of each tile?

Do I have to add links to every walkable neighbour tile of each tile?

Yes! You got it right. Your graph would be a grid. If you allow diagonal moves, then each node would have 8 neighbors. If you can only move horizontally and vertically, then each node would have just four neighbors.

To make cells impassible, I think you can try two options:

  1. Once enemy stands on a cell, then drop all connections from this cell and restore all connections for the cell where your agent has came from. When you perform path finding for a single agent, you'd have to connect it back to the grid.
  2. In your distance() function you can check if cell is taken, and if yes, return Number.POSITIVE_INFINITY - that should make this cell hugely expensive and agents would avoid it.
commented

Hey thanks for the reply.

I added links to all cells and can confirm now it can find path to target.

I'm still struggling with the distance() function though.

Seems like the toNode parameter is the destination node, in my case where the player is (fromNode would be where the monster is standing). How can I use distance() to set the weight of the next node and not the destination node?

commented

Quick update for anyone who's having a similar issue..

I did below which worked.

path.aStar(graph, {
	distance(fromNode: any, toNode: any, link: any) {
		if (link.data.weight > 0) return link.data.weight;
		let dx = fromNode.data.x - toNode.data.x;
		let dy = fromNode.data.y - toNode.data.y;

		return Math.sqrt(dx * dx + dy * dy);
	},
	heuristic(fromNode: any, toNode: any) {
		let dx = fromNode.data.x - toNode.data.x;
		let dy = fromNode.data.y - toNode.data.y;

		return Math.sqrt(dx * dx + dy * dy);
	},
});

When I initialise the grid I create every node and links between every node and its neighbours.

My grid has collisions like walls and such, when I create those object I just set the links between the object cell and its neighbours to Number.POSITIVE_INFINITY.

When player or monster moves, I do it in two steps.

  1. get the links between currently standing cell and all its neighbours, set the weight of them to 0
  2. get the links between the cell the object is moving to and all its neighbours and set the weight of them to Number.POSITIVE_INFINITY

After making these changes it's all working great and more importantly, awesome performance.
I've tried many other libraries but this one so far is the best.

The only small issue is I am using TypeScript and there's no @types for this library, so had to set every type to any :P which is not a big deal for now.. I'm just happy it works!