Computer Science Canada [Tutorial] Simple obstacle detection/path-finding |
Author: | NikG [ Thu Apr 20, 2006 1:53 pm ] | ||||||||||
Post subject: | [Tutorial] Simple obstacle detection/path-finding | ||||||||||
Welcome to my first tutorial... turned out to be a lot longer than I thought. I hope some of you find it useful. Intro Let's say you have an object that needs to move from point A to point B. The shortest distance from A to B, obviously, is a straight line. However, let's say there lies an obstacle in the straight-path between A and B. What then? Well that's where obstacle detection (aka path-finding) comes in. The tutorial is on simple obstacle detection (not to be confused with collision detection), mostly for use in games. I found I needed this while working on my secret project. I did some research on the matter, and found out about the cool A* (A-star) algorithm used in path-finding, but I wanted something simpler. Well here is my solution. Files Only 1. Attached below is the full source code for my program (130 or so lines including spaces; written in Turing 4.0.4c but it should work on previous versions). I will be going over it section by section in this tutorial. Note: I'm sure the attached code can be made a lot more efficient. The reason you'll notice some not terribly necessary code is that, like I said above, this was written to be used in a game. Therefore there might be functions/procedures that seem like overkill here but are there because I would probably want them in the full code for a game. Anyways, download the code below and try it. If you think you can, try changing the obstacle location (remember to update the height/width variables if you do) to test my path-finding. Let's get into the code. Tutorial
drawGrid draws a visual representation of the grid.
PathContainsObstacle, as the name and comment implies, checks for an obstacle from x1,y1 to x2,y2 via simple 8-way movement. ObstacleRoute is used to define a temporary route around the obstacle once PathContainsObstacle returns true. This is done by splitting the route into 3 stages: Current location to point A (just above or below the start of the obstacle); point A to point B (the end of the obstacle), point B to the final destination.
(Let me know if I went through all of that too fast) Time for some testing. Go ahead and try changing the location of the obstacles. You can do this by changing the lower/upper bounds of the for loop.
Limitations Several! But that's to be expected... this is a SIMPLE path-finding. - Obstacles must have simple shapes (for this code, rectangles only). - This will not work if there is an obstacle in the way of the temporary route created by ObstacleRoute. You will need to change my code and probably implement a little recursion to get around many obstacles located close to each other. - Obviously, this is limited to 8-way movement using an array for a grid. (For my purposes, what I needed was 360-degree movement without using an array... still trying to figure that out ) Well, that's it. I'd love to hear whether you found this useful or not. I'd also be particulary interested in those who think they have a better solution than mine. (Remember, my goal was simplicity, not efficiency.) If I notice interest in this tutorial, I might add a part 2 to this tutorial which shows how the A* method works and, if I get lucky, I'll figure out how to do this without the use of an array and post that in part 3. Stay tuned. |
Author: | MysticVegeta [ Thu Apr 20, 2006 5:23 pm ] |
Post subject: | |
Why not use DFS? or even better, BFS for pathfinding its way less code... |
Author: | Tony [ Thu Apr 20, 2006 9:35 pm ] | ||
Post subject: | |||
aren't DFS and BFS ment for classic maze soluving? There are problems if there are open spaces or worst yet, loops within the maze. A* is a fairly good algorythm for path-finding in open spaces with obstacles. NikG - the problem with your code is that it's way to specialized.
It works only for a single object of a defined shape and location. I think you should give A* another shot. (btw, when dealing with this kind of tutorials, it is quite benificiary to include pictures for the sake of visualization.) |
Author: | NikG [ Thu Apr 20, 2006 10:12 pm ] | ||
Post subject: | |||
Oh I agree, my code is highly specialized. But keep in mind that this was a small grid (10x10) with only one obstacle. In a real program, you'd probably want a separate array keeping track of all obstacle properties (startx, starty, endx, endy). Also, since your grid would almost definitely be bigger, it would be beneficial to compartmentalize my code so that it can be called by passing the location of the object and destination along with the array of obstacles.
Edit: as for pics, I agree visuals would help, but at the same time my example is pretty simple and should be a snap to follow along with. |
Author: | zylum [ Thu Apr 20, 2006 11:27 pm ] |
Post subject: | |
Tony wrote: aren't DFS and BFS ment for classic maze soluving? There are problems if there are open spaces or worst yet, loops within the maze.
A* is a fairly good algorythm for path-finding in open spaces with obstacles. Actually only DFS has a problem with open spaces, and neighter has a problem with loops within a maze. BFS is not a bad algorithm to use for pathfinding for a beginner as it is much easier to code than A*. If you are skeptical about the speed of BFS, i submitted a BFS class in turing source forum. you will notice that the speed is more than fast enough for the purpose of being used in turing games. |