Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage in a grid based system #9

Open
minotaurrr opened this issue Feb 24, 2019 · 3 comments
Open

Usage in a grid based system #9

minotaurrr opened this issue Feb 24, 2019 · 3 comments

Comments

@minotaurrr
Copy link

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?

@anvaka
Copy link
Owner

anvaka commented Feb 25, 2019

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.

@minotaurrr
Copy link
Author

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?

@minotaurrr
Copy link
Author

minotaurrr commented Feb 26, 2019

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants