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

来源:互联网 发布:阿卡索外教怎么样知乎 编辑:程序博客网 时间:2024/05/17 01:39

转: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. }  
原创粉丝点击