A* pathfinder (bmx)
Community Forums/Showcase/A* pathfinder (bmx)
| ||
It's actually "Breadth-first pathfinder" Here's an easy to use pathfinder, made it as portable as possible. Uses only 4 functions. Supports 2D and 3D maps (map's depth). The pathmap is filled with flags like: PATH_TOP, PATH_BOTTOM, PATH_LEFT, PATH_RIGHT, PATH_CEIL, PATH_FLOOR, PATH_ALL As you can see it doesn't support just 1/0 maps, but also can handle walls (hope you understand what i mean :) The path returned by FindPath() is a string (something like "11444422222222223331123") where 1 - north, 2 - south, 3 - west, 4 - east, 5 - up, 6 - down. Win32 executable ![]() Function list: CreatePathmap:TPathmap(width:Long, height:Long, depth:Long = 1) PathmapSlot(this:TPathmap, flags:Int, x:Long, y:Long, z:Long = 0) ' Used to fill pathmap with information FindPath:String(this:TPathmap, x1:Long, y1:Long, z1:Long, x2:Long, y2:Long, z2:Long) ' finds the path in a pathmap from position x1, y1, z1 to x2, y2, z2 FreePathmap(this:TPathmap) Example: SuperStrict Graphics(800, 600) SeedRnd(MilliSecs()) Global map_width:Int = 80 Global map_height:Int = 60 Include "pathfind.bmx" ' Create level Global map:Int[map_width, map_height] For Local y:Int = 0 To map_height -1 For Local x:Int = 0 To map_width - 1 If Rand(0, 5) < 2 Then map[x, y] = PATH_ALL Next Next ' Create pathmap Global pathmap:TPathmap = CreatePathmap:TPathmap(map_width, map_height) Global path:String = "" ' Copy level to pathmap For Local y:Long = 0 To map_height -1 For Local x:Long = 0 To map_width - 1 PathmapSlot(pathmap, map[x, y], x, y) Next Next While Not KeyHit(KEY_ESCAPE) Cls() ' Draw level For Local y:Int = 0 To map_height -1 For Local x:Int = 0 To map_width - 1 If CheckFlag(map[x, y], PATH_ALL) SetColor(255, 0, 0) Else SetColor(255, 255, 255) EndIf DrawRect(x * 10, y * 10, 10, 10) Next Next ' 1 - north, 2 - south, 3 - west, 4 - east, 5 - up, 6 - down path = FindPath(pathmap, map_width / 2, map_height / 2, 0, MouseX() / 10.0, MouseY() / 10.0, 0) ' Draw the PATH If Len(path) > 0 SetColor(0, 0, 255) Local x:Long = map_width / 2, y:Long = map_height / 2 For Local i:Int = 1 To Len(path) Select Mid(path, i, 1) Case "1" y :- 1 Case "2" y :+ 1 Case "3" x :- 1 Case "4" x :+ 1 End Select DrawOval(x * 10, y * 10, 10, 10) Next EndIf Flip() Wend FreePathmap(pathmap) Engine ("pathfind.bmx"): |
| ||
Freaking wonderful work :-) Can't test it but thats the simplest bit of code i've seen doing this- ease of use wise! |
| ||
sorry to be a sod here but is it REALLY an A* pathfinder or just _A_ pathfinder i even remember casey's list of alternate names for pathfinders calling themselves A* A nother path finder A* 's in their eyes path finder ok i can only remember two but if its not A* it shouldnt be called A* |
| ||
nothing to be sorry about, that's why i added it here to get feedback. I've read articles about different search algorithms and if i'm correct then this is my engine's algo? |
| ||
then as its not A* its kinda like calling a digestive biscuit a hobnob cos thats a biscuit too ;) maybe its cos A* is well known and becoming a catch all for pathfinding like hoovering with a dyson |
| ||
Well, my friend taught me that Breadth-first search algo, but I thought it was A* :( |
| ||
taken from the same link http://en.wikipedia.org/wiki/A%2A_search_algorithm i have no idea which is truely the best A* is the most well known that is for sure is it the best? id be lying if i said i knew either way all i was doing was sticking me oar in and being a sod about a possible misnaming of it ;) |
| ||
We've ran into a problem coz i can't change the topic! |
| ||
awesome, now convert it to b3d and c++ |
| ||
(that was not a request) |
| ||
there are good A* libs for B3D already done...as well as few other approaches |
| ||
the only path finding i do is when im ratted trying to make my way home from some random pub or another :p |
| ||
This is very well done. My small request: add diagonal spaces to the pathfinding algorithm. |
| ||
Current and Diagonal space flags wouldn't fit in one byte anymore so the pathmap would be instantly twice the size and FindPath() would return Chr(0)...Chr(17). So i'ts possible that i'll do it :P I'll add diagonal-space-support parameter to CreatePathmap() and rest of the engine would remain the same, except there are 12 more flags. [EDIT] Hmmm, 12 more flags wouldn't fit to even 2 bytes :( I don't know how exactly bites shiftings works to use it with 3 bytes. There is no 3 byte variable type, so i'd need to poke the 3 ones with 3 different PokeByte()s. Does the FLAG256 fit into 1 byte? ... Const FLAG64:Int = $40 Const FLAG128:Int = $80 Const FLAG256:Int = $100 Const FLAG512:Int = $200 ... |
| ||
Surely when the monster/entity whatever is following the path then just analyse the next 3 moves and if it goes north east north then make a diagonal move and skip forward 2 places? I guess it's extra processing versus extra memory and in both cases I doubt it'd be that much extra to worry about. |
| ||
You can't really do that. As, the option to go diagonal adds more optimization choices. So, the path will more than likely be even more different. |
| ||
Yeh I guess so, looking at the map above you can see where areas could be cut across diagonally, but it still might be a comprise to stop entities behaving in a slightly less mechanical way. |
| ||
B3D version (translation courteousy of bram) pathinc.bb: pathtest.bb: |
| ||
nice :) I'm too busy with other projects to finish the corner code for this pathfind engine :( |