A*寻路 -- 弗洛伊德(Floyd)算法

转:http://www.itweb2.com/article/system/317.htm

 

弗洛伊德(Floyd)算法过程:
1、用D[v][w]记录每一对顶点的最短距离。
2、依次扫描每一个点,并以其为基点再遍历所有每一对顶点D[][]的值,看看是否可用过该基点让这对顶点间的距离更小。
算法理解:
最短距离有三种情况:
1、两点的直达距离最短。(如下图<v,x>)
2、两点间只通过一个中间点而距离最短。(图<v,u>)
3、两点间用通过两各以上的顶点而距离最短。(图<v,w>)

对于第一种情况:在初始化的时候就已经找出来了且以后也不会更改到。
对于第二种情况:弗洛伊德算法的基本操作就是对于每一对顶点,遍历所有其它顶点,看看可否通过这一个顶点让这对顶点距离更短,也就是遍历了图中所有的三角形(算法中对同一个三角形扫描了九次,原则上只用扫描三次即可,但要加入判断,效率更低)。
对 于第三种情况:如下图的五边形,可先找一点(比如x,使<v,u>=2),就变成了四边形问题,再找一点(比如y,使<u,w>=2),可变成三角形问题了(v,u,w),也就变成第二种情况了,由此对于n边形也可以一步步转化成四边形三角形问题。(这里面不用担心哪个点要 先找哪个点要后找,因为找了任一个点都可以使其变成(n-1)边形的问题)。

 

 


 

使用前

 

使用后

 

其本思路:

  1. 使用A*得出基本路径
  2. 删除路径中方向相同的节点 比如 [0,1],[0,2],[0,3],[1,2] 可表现为 [0,1][0,3][1,2]
  3. 把余下的节点做为转角,代入flody算法进行计算,最后得出最简洁的方法。

在用flody计算两两转角是否连通时,需要获得一直线上经过的格子。可参考:http://25swf.blogbus.com/logs/82350359.html

flody算法:参考 http://www.itweb2.com/article/system/317.htm 
A*参考:http://eidiot.net/2007/04/17/a-star-pathfinding/

 

Java代码   收藏代码
  1. package {  
  2.     /** 
  3.      * ... 
  4.      * @author sliz http://game-develop.net/blog/ 
  5.      */  
  6.     import flash.display.Bitmap;  
  7.     import flash.display.BitmapData;  
  8.     import flash.display.Sprite;  
  9.     import flash.display.StageAlign;  
  10.     import flash.display.StageScaleMode;  
  11.     import flash.events.Event;  
  12.     import flash.events.MouseEvent;  
  13.     import flash.geom.Point;  
  14.     import flash.geom.Rectangle;  
  15.     import flash.text.TextField;  
  16.     import flash.utils.getTimer;  
  17.     import sliz.miniui.Button;  
  18.     import sliz.miniui.Checkbox;  
  19.     import sliz.miniui.Label;  
  20.     import sliz.miniui.LabelInput;  
  21.     import sliz.miniui.layouts.BoxLayout;  
  22.     import sliz.miniui.Window;  
  23.    
  24.     public class Game2 extends Sprite {  
  25.         private var _cellSize:int = 5;  
  26.         private var _grid:Grid;  
  27.         private var _player:Sprite;  
  28.         private var _index:int;  
  29.         private var _path:Array;  
  30.    
  31.         private var tf:Label;  
  32.         private var astar:AStar;  
  33.    
  34.         private var path:Sprite = new Sprite();  
  35.         private var image:Bitmap = new Bitmap(new BitmapData(11));  
  36.         private var imageWrapper:Sprite = new Sprite();  
  37.    
  38.         public function Game2(){  
  39.             stage.align = StageAlign.TOP_LEFT;  
  40.             stage.scaleMode = StageScaleMode.NO_SCALE;  
  41.             addChild(imageWrapper);  
  42.             imageWrapper.addChild(image);  
  43.             makePlayer();  
  44.    
  45.             var w:Window = new Window(this2020"tool");  
  46.             numCols = new LabelInput("numCols ""numCols");  
  47.             numCols.setValue("50");  
  48.             w.add(numCols);  
  49.             numRows = new LabelInput("numRows ""numRows");  
  50.             w.add(numRows);  
  51.             numRows.setValue("50");  
  52.             cellSize = new LabelInput("cellSize""cellSize");  
  53.             cellSize.setValue("10");  
  54.             w.add(cellSize);  
  55.             density = new LabelInput("density ""density");  
  56.             density.setValue("0.1");  
  57.             w.add(density);  
  58.             isEight = new Checkbox("是否8方向");  
  59.             isEight.setToggle(true);  
  60.             w.add(isEight);  
  61.             tf = new Label("info");  
  62.             w.add(tf);  
  63.             w.add(new sliz.miniui.Link("author sliz"));  
  64.             w.add(new sliz.miniui.Link("source""http://code.google.com/p/actionscriptiui/"));  
  65.             var btn:Button = new Button("新建"00null, newMap);  
  66.             w.add(btn, null0.8);  
  67.             w.setLayout(new BoxLayout(w, 15));  
  68.             w.doLayout();  
  69.             imageWrapper.addEventListener(MouseEvent.CLICK, onGridClick);  
  70.             addEventListener(Event.ENTER_FRAME, onEnterFrame);  
  71.             imageWrapper.addChild(path);  
  72.             makeGrid();  
  73.         }  
  74.    
  75.         private function newMap(e:Event):void {  
  76.             makeGrid();  
  77.         }  
  78.    
  79.         private function changeMode(e:Event):void {  
  80.         /*if (_grid.getType()==1) { 
  81.            _grid.calculateLinks(0); 
  82.            (e.currentTarget as Button).text = "  四方向  "; 
  83.            }else { 
  84.            _grid.calculateLinks(1); 
  85.            (e.currentTarget as Button).text = "  八方向  "; 
  86.          }*/  
  87.         }  
  88.    
  89.         private function makePlayer():void {  
  90.             _player = new Sprite();  
  91.             _player.graphics.beginFill(0xff00ff);  
  92.             _player.graphics.drawCircle(002);  
  93.             _player.graphics.endFill();  
  94.             imageWrapper.addChild(_player);  
  95.         }  
  96.    
  97.         private function makeGrid():void {  
  98.             var rows:int = int(numRows.getValue());  
  99.             var cols:int = int(numCols.getValue());  
  100.             _cellSize = int(cellSize.getValue());  
  101.             _grid = new Grid(cols, rows);  
  102.             for (var i:int = 0; i < rows * cols * Number(density.getValue()); i++){  
  103.                 _grid.setWalkable(Math.floor(Math.random() * cols), Math.floor(Math.random() * rows), false);  
  104.             }  
  105.             _grid.setWalkable(00true);  
  106.             _grid.setWalkable(cols / 2, rows / 2false);  
  107.             if (isEight.getToggle())  
  108.                 _grid.calculateLinks();  
  109.             else  
  110.                 _grid.calculateLinks(1);  
  111.             astar = new AStar(_grid);  
  112.             drawGrid();  
  113.             isClick = false;  
  114.             _player.x = 0;  
  115.             _player.y = 0;  
  116.             path.graphics.clear();  
  117.         }  
  118.    
  119.    
  120.         private function drawGrid():void {  
  121.             image.bitmapData = new BitmapData(_grid.numCols * _cellSize, _grid.numRows * _cellSize, false0xffffff);  
  122.             for (var i:int = 0; i < _grid.numCols; i++){  
  123.                 for (var j:int = 0; j < _grid.numRows; j++){  
  124.                     var node:Node = _grid.getNode(i, j);  
  125.                     if (!node.walkable){  
  126.                         image.bitmapData.fillRect(new Rectangle(i * _cellSize, j * _cellSize, _cellSize, _cellSize), getColor(node));  
  127.                     }  
  128.                 }  
  129.             }  
  130.         }  
  131.    
  132.         private function getColor(node:Node):uint {  
  133.             if (!node.walkable)  
  134.                 return 0;  
  135.             if (node == _grid.startNode)  
  136.                 return 0xcccccc;  
  137.             if (node == _grid.endNode)  
  138.                 return 0xcccccc;  
  139.             return 0xffffff;  
  140.         }  
  141.    
  142.         private function onGridClick(event:MouseEvent):void {  
  143.             var xpos:int = Math.floor(mouseX / _cellSize);  
  144.             var ypos:int = Math.floor(mouseY / _cellSize);  
  145.             xpos = Math.min(xpos, _grid.numCols - 1);  
  146.             ypos = Math.min(ypos, _grid.numRows - 1);  
  147.             _grid.setEndNode(xpos, ypos);  
  148.    
  149.             xpos = Math.floor(_player.x / _cellSize);  
  150.             ypos = Math.floor(_player.y / _cellSize);  
  151.             _grid.setStartNode(xpos, ypos);  
  152.             findPath();  
  153.             //path.graphics.clear();  
  154.             //path.graphics.lineStyle(0, 0xff0000,0.5);  
  155.             //path.graphics.moveTo(_player.x, _player.y);  
  156.         }  
  157.    
  158.         private function findPath():void {  
  159.             var time:int = getTimer();  
  160.             if (astar.findPath()){  
  161.                 _index = 0;  
  162.                 isClick = true;  
  163.    
  164.                 astar.floyd();  
  165.                 _path = astar.floydPath;  
  166.                 time = getTimer() - time;  
  167.                 tf.text = time + "ms   length:" + astar.path.length;  
  168.                 trace(astar.floydPath);  
  169.                 path.graphics.clear();  
  170.                 for (var i:int = 0; i < astar.floydPath.length; i++){  
  171.                     var p:Node = astar.floydPath[i];  
  172.                     path.graphics.lineStyle(00xff0000);  
  173.                     path.graphics.drawCircle((p.x + 0.5) * _cellSize, (p.y + 0.5) * _cellSize, 2);  
  174.    
  175.                     path.graphics.lineStyle(00xff00000.5);  
  176.                     path.graphics.moveTo(_player.x, _player.y);  
  177.                 }  
  178.             } else {  
  179.                 time = getTimer() - time;  
  180.                 tf.text = time + "ms 找不到";  
  181.             }  
  182.         }  
  183.    
  184.         private var isClick:Boolean = false;  
  185.         private var numCols:LabelInput;  
  186.         private var numRows:LabelInput;  
  187.         private var cellSize:LabelInput;  
  188.         private var density:LabelInput;  
  189.         private var isEight:Checkbox;  
  190.    
  191.         private function onEnterFrame(event:Event):void {  
  192.             if (!isClick){  
  193.                 return;  
  194.             }  
  195.             var targetX:Number = _path[_index].x * _cellSize + _cellSize / 2;  
  196.             var targetY:Number = _path[_index].y * _cellSize + _cellSize / 2;  
  197.             var dx:Number = targetX - _player.x;  
  198.             var dy:Number = targetY - _player.y;  
  199.             var dist:Number = Math.sqrt(dx * dx + dy * dy);  
  200.             if (dist < 1){  
  201.                 _index++;  
  202.                 if (_index >= _path.length){  
  203.                     isClick = false;  
  204.                 }  
  205.             } else {  
  206.                 _player.x += dx * .5;  
  207.                 _player.y += dy * .5;  
  208.                 path.graphics.lineTo(_player.x, _player.y);  
  209.             }  
  210.         }  
  211.     }  
  212. }  
  213.    
  214. import flash.geom.Point;  
  215.    
  216. class AStar {  
  217.     //private var _open:Array;  
  218.     private var _open:BinaryHeap;  
  219.     private var _grid:Grid;  
  220.     private var _endNode:Node;  
  221.     private var _startNode:Node;  
  222.     private var _path:Array;  
  223.     private var _floydPath:Array;  
  224.     public var heuristic:Function;  
  225.     private var _straightCost:Number = 1.0;  
  226.     private var _diagCost:Number = Math.SQRT2;  
  227.     private var nowversion:int = 1;  
  228.    
  229.     public function AStar(grid:Grid){  
  230.         this._grid = grid;  
  231.         heuristic = euclidian2;  
  232.    
  233.     }  
  234.    
  235.     private function justMin(x:Object, y:Object):Boolean {  
  236.         return x.f < y.f;  
  237.     }  
  238.    
  239.     public function findPath():Boolean {  
  240.         _endNode = _grid.endNode;  
  241.         nowversion++;  
  242.         _startNode = _grid.startNode;  
  243.         //_open = [];  
  244.         _open = new BinaryHeap(justMin);  
  245.         _startNode.g = 0;  
  246.         return search();  
  247.     }  
  248.    
  249.     public function floyd():void {  
  250.         if (path == null)  
  251.             return;  
  252.         _floydPath = path.concat();  
  253.         var len:int = _floydPath.length;  
  254.         if (len > 2){  
  255.             var vector:Node = new Node(00);  
  256.             var tempVector:Node = new Node(00);  
  257.             floydVector(vector, _floydPath[len - 1], _floydPath[len - 2]);  
  258.             for (var i:int = _floydPath.length - 3; i >= 0; i--){  
  259.                 floydVector(tempVector, _floydPath[i + 1], _floydPath[i]);  
  260.                 if (vector.x == tempVector.x && vector.y == tempVector.y){  
  261.                     _floydPath.splice(i + 11);  
  262.                 } else {  
  263.                     vector.x = tempVector.x;  
  264.                     vector.y = tempVector.y;  
  265.                 }  
  266.             }  
  267.         }  
  268.         len = _floydPath.length;  
  269.         for (i = len - 1; i >= 0; i--){  
  270.             for (var j:int = 0; j <= i - 2; j++){  
  271.                 if (floydCrossAble(_floydPath[i], _floydPath[j])){  
  272.                     for (var k:int = i - 1; k > j; k--){  
  273.                         _floydPath.splice(k, 1);  
  274.                     }  
  275.                     i = j;  
  276.                     len = _floydPath.length;  
  277.                     break;  
  278.                 }  
  279.             }  
  280.         }  
  281.     }  
  282.    
  283.     private function floydCrossAble(n1:Node, n2:Node):Boolean {  
  284.         var ps:Array = bresenhamNodes(new Point(n1.x, n1.y), new Point(n2.x, n2.y));  
  285.         for (var i:int = ps.length - 2; i > 0; i--){  
  286.             if (!_grid.getNode(ps[i].x, ps[i].y).walkable){  
  287.                 return false;  
  288.             }  
  289.         }  
  290.         return true;  
  291.     }  
  292.    
  293.     private function bresenhamNodes(p1:Point, p2:Point):Array {  
  294.         var steep:Boolean = Math.abs(p2.y - p1.y) > Math.abs(p2.x - p1.x);  
  295.         if (steep){  
  296.             var temp:int = p1.x;  
  297.             p1.x = p1.y;  
  298.             p1.y = temp;  
  299.             temp = p2.x;  
  300.             p2.x = p2.y;  
  301.             p2.y = temp;  
  302.         }  
  303.         var stepX:int = p2.x > p1.x ? 1 : (p2.x < p1.x ? -1 : 0);  
  304.         var stepY:int = p2.y > p1.y ? 1 : (p2.y < p1.y ? -1 : 0);  
  305.         var deltay:Number = (p2.y - p1.y) / Math.abs(p2.x - p1.x);  
  306.         var ret:Array = [];  
  307.         var nowX:Number = p1.x + stepX;  
  308.         var nowY:Number = p1.y + deltay;  
  309.         if (steep){  
  310.             ret.push(new Point(p1.y, p1.x));  
  311.         } else {  
  312.             ret.push(new Point(p1.x, p1.y));  
  313.         }  
  314.         while (nowX != p2.x){  
  315.             var fy:int = Math.floor(nowY)  
  316.             var cy:int = Math.ceil(nowY);  
  317.             if (steep){  
  318.                 ret.push(new Point(fy, nowX));  
  319.             } else {  
  320.                 ret.push(new Point(nowX, fy));  
  321.             }  
  322.             if (fy != cy){  
  323.                 if (steep){  
  324.                     ret.push(new Point(cy, nowX));  
  325.                 } else {  
  326.                     ret.push(new Point(nowX, cy));  
  327.                 }  
  328.             }  
  329.             nowX += stepX;  
  330.             nowY += deltay;  
  331.         }  
  332.         if (steep){  
  333.             ret.push(new Point(p2.y, p2.x));  
  334.         } else {  
  335.             ret.push(new Point(p2.x, p2.y));  
  336.         }  
  337.         return ret;  
  338.     }  
  339.    
  340.     private function floydVector(target:Node, n1:Node, n2:Node):void {  
  341.         target.x = n1.x - n2.x;  
  342.         target.y = n1.y - n2.y;  
  343.     }  
  344.    
  345.     public function search():Boolean {  
  346.         var node:Node = _startNode;  
  347.         node.version = nowversion;  
  348.         while (node != _endNode){  
  349.             var len:int = node.links.length;  
  350.             for (var i:int = 0; i < len; i++){  
  351.                 var test:Node = node.links[i].node;  
  352.                 var cost:Number = node.links[i].cost;  
  353.                 var g:Number = node.g + cost;  
  354.                 var h:Number = heuristic(test);  
  355.                 var f:Number = g + h;  
  356.                 if (test.version == nowversion){  
  357.                     if (test.f > f){  
  358.                         test.f = f;  
  359.                         test.g = g;  
  360.                         test.h = h;  
  361.                         test.parent = node;  
  362.                     }  
  363.                 } else {  
  364.                     test.f = f;  
  365.                     test.g = g;  
  366.                     test.h = h;  
  367.                     test.parent = node;  
  368.                     _open.ins(test);  
  369.                     test.version = nowversion;  
  370.                 }  
  371.    
  372.             }  
  373.             if (_open.a.length == 1){  
  374.                 return false;  
  375.             }  
  376.             node = _open.pop() as Node;  
  377.         }  
  378.         buildPath();  
  379.         return true;  
  380.     }  
  381.    
  382.     private function buildPath():void {  
  383.         _path = [];  
  384.         var node:Node = _endNode;  
  385.         _path.push(node);  
  386.         while (node != _startNode){  
  387.             node = node.parent;  
  388.             _path.unshift(node);  
  389.         }  
  390.     }  
  391.    
  392.     public function get path():Array {  
  393.         return _path;  
  394.     }  
  395.    
  396.     public function get floydPath():Array {  
  397.         return _floydPath;  
  398.     }  
  399.    
  400.     public function manhattan(node:Node):Number {  
  401.         return Math.abs(node.x - _endNode.x) + Math.abs(node.y - _endNode.y);  
  402.     }  
  403.    
  404.     public function manhattan2(node:Node):Number {  
  405.         var dx:Number = Math.abs(node.x - _endNode.x);  
  406.         var dy:Number = Math.abs(node.y - _endNode.y);  
  407.         return dx + dy + Math.abs(dx - dy) / 1000;  
  408.     }  
  409.    
  410.     public function euclidian(node:Node):Number {  
  411.         var dx:Number = node.x - _endNode.x;  
  412.         var dy:Number = node.y - _endNode.y;  
  413.         return Math.sqrt(dx * dx + dy * dy);  
  414.     }  
  415.    
  416.     private var TwoOneTwoZero:Number = 2 * Math.cos(Math.PI / 3);  
  417.    
  418.     public function chineseCheckersEuclidian2(node:Node):Number {  
  419.         var y:int = node.y / TwoOneTwoZero;  
  420.         var x:int = node.x + node.y / 2;  
  421.         var dx:Number = x - _endNode.x - _endNode.y / 2;  
  422.         var dy:Number = y - _endNode.y / TwoOneTwoZero;  
  423.         return sqrt(dx * dx + dy * dy);  
  424.     }  
  425.    
  426.     private function sqrt(x:Number):Number {  
  427.         return Math.sqrt(x);  
  428.     }  
  429.    
  430.     public function euclidian2(node:Node):Number {  
  431.         var dx:Number = node.x - _endNode.x;  
  432.         var dy:Number = node.y - _endNode.y;  
  433.         return dx * dx + dy * dy;  
  434.     }  
  435.    
  436.     public function diagonal(node:Node):Number {  
  437.         var dx:Number = Math.abs(node.x - _endNode.x);  
  438.         var dy:Number = Math.abs(node.y - _endNode.y);  
  439.         var diag:Number = Math.min(dx, dy);  
  440.         var straight:Number = dx + dy;  
  441.         return _diagCost * diag + _straightCost * (straight - 2 * diag);  
  442.     }  
  443. }  
  444.    
  445.    
  446. class BinaryHeap {  
  447.     public var a:Array = [];  
  448.     public var justMinFun:Function = function(x:Object, y:Object):Boolean {  
  449.         return x < y;  
  450.     };  
  451.    
  452.     public function BinaryHeap(justMinFun:Function = null){  
  453.         a.push(-1);  
  454.         if (justMinFun != null)  
  455.             this.justMinFun = justMinFun;  
  456.     }  
  457.    
  458.     public function ins(value:Object):void {  
  459.         var p:int = a.length;  
  460.         a[p] = value;  
  461.         var pp:int = p >> 1;  
  462.         while (p > 1 && justMinFun(a[p], a[pp])){  
  463.             var temp:Object = a[p];  
  464.             a[p] = a[pp];  
  465.             a[pp] = temp;  
  466.             p = pp;  
  467.             pp = p >> 1;  
  468.         }  
  469.     }  
  470.    
  471.     public function pop():Object {  
  472.         var min:Object = a[1];  
  473.         a[1] = a[a.length - 1];  
  474.         a.pop();  
  475.         var p:int = 1;  
  476.         var l:int = a.length;  
  477.         var sp1:int = p << 1;  
  478.         var sp2:int = sp1 + 1;  
  479.         while (sp1 < l){  
  480.             if (sp2 < l){  
  481.                 var minp:int = justMinFun(a[sp2], a[sp1]) ? sp2 : sp1;  
  482.             } else {  
  483.                 minp = sp1;  
  484.             }  
  485.             if (justMinFun(a[minp], a[p])){  
  486.                 var temp:Object = a[p];  
  487.                 a[p] = a[minp];  
  488.                 a[minp] = temp;  
  489.                 p = minp;  
  490.                 sp1 = p << 1;  
  491.                 sp2 = sp1 + 1;  
  492.             } else {  
  493.                 break;  
  494.             }  
  495.         }  
  496.         return min;  
  497.     }  
  498. }  
  499.    
  500. class Grid {  
  501.    
  502.     private var _startNode:Node;  
  503.     private var _endNode:Node;  
  504.     private var _nodes:Array;  
  505.     private var _numCols:int;  
  506.     private var _numRows:int;  
  507.    
  508.     private var type:int;  
  509.    
  510.     private var _straightCost:Number = 1.0;  
  511.     private var _diagCost:Number = Math.SQRT2;  
  512.    
  513.     public function Grid(numCols:int, numRows:int){  
  514.         _numCols = numCols;  
  515.         _numRows = numRows;  
  516.         _nodes = new Array();  
  517.    
  518.         for (var i:int = 0; i < _numCols; i++){  
  519.             _nodes[i] = new Array();  
  520.             for (var j:int = 0; j < _numRows; j++){  
  521.                 _nodes[i][j] = new Node(i, j);  
  522.             }  
  523.         }  
  524.     }  
  525.    
  526.     /** 
  527.      * 
  528.      * @param   type    0四方向 1八方向 2跳棋 
  529.      */  
  530.     public function calculateLinks(type:int = 0):void {  
  531.         this.type = type;  
  532.         for (var i:int = 0; i < _numCols; i++){  
  533.             for (var j:int = 0; j < _numRows; j++){  
  534.                 initNodeLink(_nodes[i][j], type);  
  535.             }  
  536.         }  
  537.     }  
  538.    
  539.     public function getType():int {  
  540.         return type;  
  541.     }  
  542.    
  543.     /** 
  544.      * 
  545.      * @param   node 
  546.      * @param   type    0八方向 1四方向 2跳棋 
  547.      */  
  548.     private function initNodeLink(node:Node, type:int):void {  
  549.         var startX:int = Math.max(0, node.x - 1);  
  550.         var endX:int = Math.min(numCols - 1, node.x + 1);  
  551.         var startY:int = Math.max(0, node.y - 1);  
  552.         var endY:int = Math.min(numRows - 1, node.y + 1);  
  553.         node.links = [];  
  554.         for (var i:int = startX; i <= endX; i++){  
  555.             for (var j:int = startY; j <= endY; j++){  
  556.                 var test:Node = getNode(i, j);  
  557.                 if (test == node || !test.walkable){  
  558.                     continue;  
  559.                 }  
  560.                 if (type != 2 && i != node.x && j != node.y){  
  561.                     var test2:Node = getNode(node.x, j);  
  562.                     if (!test2.walkable){  
  563.                         continue;  
  564.                     }  
  565.                     test2 = getNode(i, node.y);  
  566.                     if (!test2.walkable){  
  567.                         continue;  
  568.                     }  
  569.                 }  
  570.                 var cost:Number = _straightCost;  
  571.                 if (!((node.x == test.x) || (node.y == test.y))){  
  572.                     if (type == 1){  
  573.                         continue;  
  574.                     }  
  575.                     if (type == 2 && (node.x - test.x) * (node.y - test.y) == 1){  
  576.                         continue;  
  577.                     }  
  578.                     if (type == 2){  
  579.                         cost = _straightCost;  
  580.                     } else {  
  581.                         cost = _diagCost;  
  582.                     }  
  583.                 }  
  584.                 node.links.push(new Link(test, cost));  
  585.             }  
  586.         }  
  587.     }  
  588.    
  589.     public function getNode(x:int, y:int):Node {  
  590.         return _nodes[x][y];  
  591.     }  
  592.    
  593.     public function setEndNode(x:int, y:int):void {  
  594.         _endNode = _nodes[x][y];  
  595.     }  
  596.    
  597.     public function setStartNode(x:int, y:int):void {  
  598.         _startNode = _nodes[x][y];  
  599.     }  
  600.    
  601.     public function setWalkable(x:int, y:int, value:Boolean):void {  
  602.         _nodes[x][y].walkable = value;  
  603.     }  
  604.    
  605.     public function get endNode():Node {  
  606.         return _endNode;  
  607.     }  
  608.    
  609.     public function get numCols():int {  
  610.         return _numCols;  
  611.     }  
  612.    
  613.     public function get numRows():int {  
  614.         return _numRows;  
  615.     }  
  616.    
  617.     public function get startNode():Node {  
  618.         return _startNode;  
  619.     }  
  620.    
  621. }  
  622.    
  623. class Link {  
  624.     public var node:Node;  
  625.     public var cost:Number;  
  626.    
  627.     public function Link(node:Node, cost:Number){  
  628.         this.node = node;  
  629.         this.cost = cost;  
  630.     }  
  631.    
  632. }  
  633.    
  634. class Node {  
  635.     public var x:int;  
  636.     public var y:int;  
  637.     public var f:Number;  
  638.     public var g:Number;  
  639.     public var h:Number;  
  640.     public var walkable:Boolean = true;  
  641.     public var parent:Node;  
  642.     //public var costMultiplier:Number = 1.0;  
  643.     public var version:int = 1;  
  644.     public var links:Array;  
  645.    
  646.     //public var index:int;  
  647.     public function Node(x:int, y:int){  
  648.         this.x = x;  
  649.         this.y = y;  
  650.     }  
  651.    
  652.     public function toString():String {  
  653.         return "x:" + x + " y:" + y;  
  654.     }  
  655. }  

 

 

 

 

猜你喜欢

转载自blog.csdn.net/m0_37290785/article/details/79656042