prettymuchbryce / easystarjs

An asynchronous A* pathfinding API written in Javascript.
MIT License
1.9k stars 165 forks source link

Feature Request: Move to 'within range' of target #75

Open mikeparker opened 4 years ago

mikeparker commented 4 years ago

For example, if my player clicks on a rock, I want him to path to next to the rock.

Similarly for my ranged enemies (who can fire lets say 4 tiles distance), I want them to path to 4 squares away.

I coded a similar thing for a C# A* algorithm and I think it was possible purely through an early abort if the path reached the distance required, no pathfinding changes needed.

prettymuchbryce commented 4 years ago

This is possible with the existing implementation. Simply find the desired path and walk it until you reach the desired distance, no?

mikeparker commented 4 years ago

No because if the destination is an impassable tile easystar returns no path, unless i'm missing something?

prettymuchbryce commented 4 years ago

Hmm ok. I see the problem now. It won't work for cases like this either, even if E is passable.

[S][0][0][0][0]
[0][0][0][0][0]
[0][1][1][1][0]
[0][1][E][1][0]
[0][1][1][1][0]
[0][0][0][0][0]
[0][0][0][0][0]

S = start
E = end
0 = passable
1 = impassable

It's possible to do this now by modifying the grid between calling calculate, but this isn't advisable. We could put this into the API. It's not a breaking change. Are you imagining something like findPathWithinDistance(startX, startY, endX, endY, distance, callback)?

mikeparker commented 4 years ago

Yes, you've got it exactly right.

With the current code I was looking at:

Which is a bit of a hack but it should work.

Passing in the intended distance would be perfect!

mikeparker commented 4 years ago

Another option would be to return the best path regardless of if the path reached the destination, and have the path have a property to note if it finished or not. That way, authors can choose to either use the path to get as far as possible, or discard the path and not move.

This would work for all the scenarios above such as: a) Player wants to move to an impassable square b) Enemy wants to move towards the player who is surrounded by a fortress wall (e.g. zombies butting up against a wall) c) Enemy wants to move within X squares of the target to fire at them (Author can cancel movement when in range).

cjke commented 4 years ago

Not to be one of those people, but I really +1 on @mikeparker second idea of allowing unclosed paths. Is this something that may be added in future? Seems kind of like this question/answer: https://gamedev.stackexchange.com/questions/35253/tweaking-astar-to-find-closest-location-to-unreachable-destination