• 《AdvancED ActionScript 3.0 Animation》读书笔记(3) —— A星寻路


    public class Grid

    {

    private var _startNode:Node;

    private var _endNode:Node;

    private var _nodes:Array;

    private var _numCols:int;

    private var _numRows:int;


    /**

    * Constructor.

    */

    public function Grid(numCols:int, numRows:int)

    {

    _numCols = numCols;

    _numRows = numRows;

    _nodes = new Array();

    for(var i:int = 0; i < _numCols; i++)

    {

    _nodes[i] = new Array();

    for(var j:int = 0; j < _numRows; j++)

    {

    _nodes[i][j] = new Node(i, j);

    }

    }

    }

    ////////////////////////////////////////

    // public methods

    ////////////////////////////////////////

    /**

    * Returns the node at the given coords.


    * @param x The x coord.

    * @param y The y coord.

    */

    public function getNode(x:int, y:int):Node

    {

    return _nodes[x][y] as Node;

    }

    /**

    * Sets the node at the given coords as the end node.

    * @param x The x coord.

    * @param y The y coord.

    */

    public function setEndNode(x:int, y:int):void

    {

    _endNode = _nodes[x][y] as Node;

    }

    /**

    * Sets the node at the given coords as the start node.

    * @param x The x coord.

    * @param y The y coord.

    */

    public function setStartNode(x:int, y:int):void

    {

    _startNode = _nodes[x][y] as Node;

    }

    /**

    * Sets the node at the given coords as walkable or not.

    * @param x The x coord.

    * @param y The y coord.

    */

    public function setWalkable(x:int, y:int, value:Boolean):void

    {

    _nodes[x][y].walkable = value;

    }

    ////////////////////////////////////////

    // getters / setters

    ////////////////////////////////////////

    /**

    * Returns the end node.

    11

    */

    public function get endNode():Node

    {

    return _endNode;

    }

    /**

    * Returns the number of columns in the grid.

    */

    public function get numCols():int

    {

    return _numCols;

    }

    /**

    * Returns the number of rows in the grid.

    */

    public function get numRows():int

    {

    return _numRows;

    }

    /**

    * Returns the start node.

    */

    public function get startNode():Node

    {

    return _startNode;

    }

    }



    ===============================


    public class Node

    {

    public var x:int;


    public var y:int;

    public var f:Number;

    public var g:Number;

    public var h:Number;

    public var walkable:Boolean = true;

    public var parent:Node;

    public var costMultiplier:Number = 1.0;

    public function Node(x:int, y:int)

    {

    this.x = x;

    this.y = y;

    }

    }



    ===================================


    public class AStar

    {

    private var _open:Array;

    private var _closed:Array;

    private var _grid:Grid;

    private var _endNode:Node;

    private var _startNode:Node;

    private var _path:Array;

    // private var _heuristic:Function = manhattan;

    // private var _heuristic:Function = euclidian;

    private var _heuristic:Function = diagonal;

    private var _straightCost:Number = 1.0;

    private var _diagCost:Number = Math.SQRT2;


    public function AStar()

    {

    }


    public function findPath(grid:Grid):Boolean

    {

    _grid = grid;

    _open = new Array();

    _closed = new Array();

    _startNode = _grid.startNode;

    _endNode = _grid.endNode;

    _startNode.g = 0;

    _startNode.h = _heuristic(_startNode);

    _startNode.f = _startNode.g + _startNode.h;

    return search();

    }


    public function search():Boolean

    {

    var node:Node = _startNode;

    while(node != _endNode)

    {

    var startX:int = Math.max(0, node.x - 1);

    var endX:int = Math.min(_grid.numCols - 1, node.x + 1);

    var startY:int = Math.max(0, node.y - 1);

    var endY:int = Math.min(_grid.numRows - 1, node.y + 1);

    for(var i:int = startX; i <= endX; i++)

    {

    for(var j:int = startY; j <= endY; j++)

    {

    var test:Node = _grid.getNode(i, j);

    if(test == node ||

    !test.walkable ||

    !_grid.getNode(node.x, test.y).walkable ||

    !_grid.getNode(test.x, node.y).walkable)

    {

    continue;

    }

    var cost:Number = _straightCost;

    if(!((node.x == test.x) || (node.y == test.y)))

    {

    cost = _diagCost;

    }

    var g:Number = node.g + cost * test.costMultiplier;

    var h:Number = _heuristic(test);

    var f:Number = g + h;

    14

    if(isOpen(test) || isClosed(test))

    {

    if(test.f > f)

    {

    test.f = f;

    test.g = g;

    test.h = h;

    test.parent = node;

    }

    }

    else

    {

    test.f = f;

    test.g = g;

    test.h = h;

    test.parent = node;

    _open.push(test);

    }

    }

    }

    for(var o:int = 0; o < _open.length; o++)

    {

    }

    _closed.push(node);

    if(_open.length == 0)

    {

    trace("no path found");

    return false

    }

    _open.sortOn("f", Array.NUMERIC);

    node = _open.shift() as Node;

    }

    buildPath();

    return true;

    }


    ==================================


    private function euclidian(node:Node):Number

    {

    var dx:Number = node.x - _endNode.x;

    var dy:Number = node.y - _endNode.y;

    return Math.sqrt(dx * dx + dy * dy) * _straightCost;

    }


  • 相关阅读:
    POJ3159 Candies —— 差分约束 spfa
    POJ1511 Invitation Cards —— 最短路spfa
    POJ1860 Currency Exchange —— spfa求正环
    POJ3259 Wormholes —— spfa求负环
    POJ3660 Cow Contest —— Floyd 传递闭包
    POJ3268 Silver Cow Party —— 最短路
    POJ1797 Heavy Transportation —— 最短路变形
    POJ2253 Frogger —— 最短路变形
    POJ1759 Garland —— 二分
    POJ3685 Matrix —— 二分
  • 原文地址:https://www.cnblogs.com/cly84920/p/4426488.html
Copyright © 2020-2023  润新知