You can create 3D, 4D or nD maps and analyzers, but since that can be a little bit tricky, I’ve created a few basic 3D classes that can be found in be.dauntless.basic3d.

This is a basic example for a 3D map, using Map3D and FullClipping3DAnalyzer. Note that you could create a BasicTile3D and a Walkable3DAnalyzer, but the 2D counterparts work just as well; Map3D uses Point3D which extends the Point class that BasicTile uses and a tile is walkable or non-walkable, whether it’s 3D or 2D.

package  
{
	import be.dauntless.astar.basic3d.analyzers.FullClipping3DAnalyzer;
	import be.dauntless.astar.basic2d.BasicTile;
	import be.dauntless.astar.basic2d.analyzers.WalkableAnalyzer;
	import be.dauntless.astar.basic3d.Map3D;
	import be.dauntless.astar.basic3d.Point3D;
	import be.dauntless.astar.core.Astar;
	import be.dauntless.astar.core.AstarEvent;
	import be.dauntless.astar.core.IAstarTile;
	import be.dauntless.astar.core.PathRequest;
 
	import flash.display.Sprite;
 
	/**
	 * @author Jeroen
	 */
	public class Basic3DTest extends Sprite 
	{
 
		private var map:Map3D;
		private var astar:Astar;
		private var req:PathRequest;
		public function Basic3DTest()
		{
			var dataMap:Array = new Array(
				new Array(
					new Array(0,0,0,0),
					new Array(0,1,1,0),
					new Array(0,1,1,0),
					new Array(0,0,0,0)),
				new Array(
					new Array(0,1,1,0),
					new Array(0,1,1,0),
					new Array(0,0,0,0),
					new Array(0,0,0,0)),
				new Array(
					new Array(0,0,0,0),
					new Array(0,0,0,0),
					new Array(1,1,0,0),
					new Array(1,1,0,0)),
				new Array(
					new Array(1,0,1,0),
					new Array(0,0,1,1),
					new Array(0,0,0,0),
					new Array(1,0,0,1))
				);
 
 
			//create a new map and fill it with BasicTiles
			map = new Map3D(4, 4, 4, 100);
 
			for(var z:int = 0; z < dataMap.length; z++)
			{
				for(var y:Number = 0; y< dataMap[z].length; y++)
				{
					for(var x:Number = 0; x< (dataMap[z][y] as Array).length; x++)
					{
						map.setTile(new BasicTile(100, new Point3D(x, y, z), (dataMap[z][y][x]==0)));
					}
				}
			}
 
			//create the Astar instance and add the listeners
			astar = new Astar(true);
			astar.addEventListener(AstarEvent.PATH_FOUND, onPathFound);
			astar.addEventListener(AstarEvent.PATH_NOT_FOUND, onPathNotFound);
 
			//create a new PathRequest
			req = new PathRequest(IAstarTile(map.getTileAt(new Point3D(0, 0, 0))), IAstarTile(map.getTileAt(new Point3D(2, 3, 3))), map);
 
			//WalkableAnalyzer is a 2D analyzer, but you can use it on a 3D map since it just checks for walkability
			astar.addAnalyzer(new WalkableAnalyzer());
 
			//and you can only move horizontally/diagonally
			astar.addAnalyzer(new FullClipping3DAnalyzer());
			astar.getPath(req);
		}
 
		private function onPathNotFound(event : AstarEvent) : void
		{
			trace("path not found");
		}
 
 
		private function onPathFound(event : AstarEvent) : void
		{
			trace("Path was found: ");
			for(var i:int = 0; i<event.result.path.length;i++)
			{
				trace((event.result.path[i] as BasicTile).getPosition());
			}
		}
	}
}

This will give out the following path:

Path was found:
[Point3D (x=0, y=0, z=0)]
[Point3D (x=0, y=0, z=1)]
[Point3D (x=0, y=0, z=2)]
[Point3D (x=1, y=0, z=2)]
[Point3D (x=1, y=0, z=3)]
[Point3D (x=1, y=1, z=3)]
[Point3D (x=1, y=2, z=3)]
[Point3D (x=2, y=2, z=3)]
[Point3D (x=2, y=3, z=3)]

Found path 3D

My initial goal was to be able to create a Fantasy Tactics style game. That means 3d maps and a gravity analyzer so that you get realistic paths.

Because you are able to jump through the air, some tiles will have to be marked as air. If a tile is marked as air, or if it just doesn’t exist in the map, you can jump through it.

I’m still working on a little demo, but you can find the classes in the v1.3 download. If you can’t get it to work, just send me an email.

5 Responses to “The Third Dimension”


  1. 1 mike

    Many many thank

  2. 2 urban

    Hi, i just wondered,
    if my grid is : (S start, F finish)
    why can’t i prevent the path to go in diagonal between 2 high blocs (3) ? i dont want this to happen, as my blocs are squares.
    00000F0
    0000300
    0003030
    0000S00

  3. 3 Dauntless

    First, are you sure you need a 3D map/analyzers? It’s only needed if there are stuff like bridges or houses with multiple floors in your map. If some tiles are just “higher” than other tiles, you can use a 2D map, which is less complicated.

    To stop your hero from going diagonal in such a case, you’ll have to create your own analyzer. You can use the SmartClippingAnalyzer as a starting point. Just copy the sourcecode and change the if statements that check for getWalkable() to conditions that check if the current height is equal to the neighbour height.

  4. 4 urban

    Hi! thanks for the answer about the 2D version, i got world with Tiles from 0 to 7, But i never manage to have the 2D Pathfinder working from a floor to another. (Start on 0, and End on 3 for ex)
    Start and End on same floor works, or i get a “End tile is not a valid tile” :/

  5. 5 Dauntless

    If you want, you can send me some code at mynickname@mynickname.be. You don’t have to send me your entire project. I don’t even have Flash/Flex/FDT installed anyway. Just send the relevant pieces, and maybe I can see why it’s not working 🙂

Leave a Reply

*