findClosestByRange(exitDirection) does _not_ return the closestByRange exit tile.
-
findClosestByRange(exitDirection) returns a random tile of the correct exit but not the tile closestByRange to the invoking object.
My controller is at x9/y38, the returned closestByRange exit tile is x49/y5 while the exit literally spans the entire room and the closestByRange exit tile should be x49/y38.
Please fix - thank you!
-
controller.pos={"x":9,"y":38,"roomName":"W27N82"}
exit to W26N82 / exitDirection= 3
roomExit= {"x":49,"y":5,"roomName":"W27N82"}
exit to W28N82 / exitDirection= 7
roomExit= {"x":0,"y":29,"roomName":"W27N82"}
Totally not the closest exit tiles ... see the blue lines:
-
This is expected behavior, and believe it or not that *is* the closest by the in game math.
Take a look at the distance formula-
distance = Math.min(Math.abs(x1-x2), Math.abs(y1-y2))
Because diagonal movement counts as one movement you are able to adjust your X and Y position at the same time and it only counts as one movement instead of two. As a result your "distance" is defined as the shortest distance between either X1 and X2 or Y1 and Y2. To put it another way, if you are at 10,10 and want to move to 15, 20 your Y distance will be 10 (20-10) and the X distance 5, but since you can move your X while moving Y your actual absolute distance is going to be 10.
So lets look at the walls. By definition they are all on an edge- in this case X49. Your controller is at 9. That means the minimum amount of distance you have to travel is going to be 40 spaces. It will be impossible for you to get a distance that's shorter than this.
Now lets take a look at the Y distance. The controller is at Y38, and the "highest" exit tile is at Y1. That's a distance of only 37. Since you already know you have to travel 40 spaces to get to the edge that 37 number is basically discarded. In fact every single exit tile on the right is going to be less than 40 "y" movements away, which means that all of them are discounted when calculating distance.
To put it another way, for literally ever exit tile on the right of the room you will have a distance of "40". When sorting those squares by distance it'll actually maintain the order of the array that was passed to it, as all of them are the same value. Since the "top" exit element was the first in the array it will always be the "closest" when there's a tie on the test.
There are a few ways around this-
* Use manhattan distance instead of direct. This will give you false positives in some areas though.
* Don't route to exits- instead route to your final destination or a point in the center of the second room. This will allow the pathfinder to find the ideal route taking into account where you want to go.
-
Thank you for taking the time to point this out. I forgot about the weird diagonal thing. So it basically gives you the shortest path just "biased" towards the beginning of the data structure. Makes sense but Pythagoras disapproves.