如何使Astar寻路可以被多个敌人使用?

时间:2013-09-19 14:02:46

标签: actionscript-3 a-star

我从“AdvancED_ActionScript_Animation”电子书中学习了一个明星寻路:

  • 列表项
  • 我创建节点类Node.as。
  • 我制作网格课,Grid.as。
  • 我制作AStar课程,AStar.as。
  • 和主要的分支,Game.as。 A-star Pathfinding是工作,但只有1名球员。 如何让它在多人游戏中运作?
  

扰流板 4.Game.as:

package 
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;

public class Game extends Sprite
{
    private var _cellSize:int = 30;
    private var _grid:Grid;
    private var _player:Sprite;
    private var _index:int;
    private var _path:Array;


    public function Game()
    {
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        makePlayer();
        makeGrid();
        stage.addEventListener(MouseEvent.CLICK, onGridClick);
    }
    private function makePlayer():void
    {
        _player =new Sprite();
        _player.graphics.beginFill(0x336633);
        _player.graphics.drawCircle(0,0,5);
        _player.graphics.endFill();
        _player.x = Math.random() * 100;
        _player.y = Math.random() * 100;
        addChild(_player);
    }

    private function makeGrid():void
    {
        _grid = new Grid(10,10);
        for (var i:int =0; i < 10; i++)
        {
        _grid.setWalkable(Math.floor(Math.random()*10),
          Math.floor(Math.random()*10),false);
        }
        drawGrid();
    }
    private function drawGrid():void
    {
        graphics.clear();
        for (var i:int =0; i < _grid.numCols; i++)
        {
            for (var j:int =0; j<_grid.numRows; j++)
            {
                var node:Node = _grid.getNode(i,j);
                graphics.lineStyle(0);
                graphics.beginFill(getColor(node));
                graphics.drawRect(i *_cellSize,
                  j*_cellSize,_cellSize,
                  _cellSize);

            }
        }
    }

    private function getColor(node:Node):uint
    {
        if (! node.walkable)
        {
            return 0;
        }
        if (node == _grid.startNode)
        {
            return 0xcccccc;
        }
        if (node == _grid.endNode)
        {
            return 0xcccccc;
        }
        return 0xffffff;
    }
    private function onGridClick(event:MouseEvent):void
    {
        var xpos:int =Math.floor(mouseX/_cellSize);
        var ypos:int =Math.floor(mouseY/_cellSize);
        _grid.setEndNode(xpos,ypos);

        xpos = Math.floor(_player.x / _cellSize);
        ypos = Math.floor(_player.y / _cellSize);
        _grid.setStartNode(xpos,ypos);
        drawGrid();
        findPath();

    }
    private function findPath():void
    {        
        var astar:AStar = new AStar();
        if (astar.findPath(_grid))
        {
            _path = astar.path;
            _index = 0;
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
    }
    private function onEnterFrame(event:Event):void
    {
        var targetX:Number = _path[_index].x * _cellSize 
        + _cellSize / 2;
        var targetY:Number = _path[_index].y * _cellSize 
        + _cellSize / 2;
        var dx:Number = targetX - _player.x;
        var dy:Number = targetY - _player.y;
        var dx2:Number = targetX - _box.x;
        var dy2:Number = targetY - _box.y;
        var dist2:Number =Math.sqrt(dx2*dx2+dy2+dy2);
        var dist:Number =Math.sqrt(dx*dx+dy+dy);
        if (dist<1)
        {
            _index++;
            if (_index >= _path.length)
            {

             removeEventListener(Event.ENTER_FRAME,onEnterFrame);
            }
        }
        else
        {
            _player.x += dx * .5;
            _player.y += dy * .5;

        }


    }
}
}

1 个答案:

答案 0 :(得分:0)

我不会为你加倍努力。 (任何人都可以随意做到这一点)

您需要做的是创建一个接受起始节点和结束节点的函数,并返回路径。像这样:

public function getPath(starNode:Point, endNode:Point):Array
{
    // get your path by utilizing the astar instance
    // return that path array

    // note that I have used Points to store the x,y location
    // you'll need to apply those values to the grid before your astar call
    // using the setStarNode and setEndNode methods of the grid instance


}

然后你可以修改你的enterFrame中使用的代码,以利用包含你想要的任何玩家/敌人的路径数据的数组。

例如,您可能拥有为每个实体调用的函数,例如:

public function followPath(entity:MovieClip, pathData:Array, pathIndex:int):void
{
    // your modified code from onEnterFrame
        // replace _player variable with entity
        // replace _path variable with pathData
        // replace _index with pathIndex 
}

如果你足够了解OOP,你可能想为你的玩家/敌人实体创建一个具有pathData和pathIndex属性的类。如果你这样做,那么你可以调用一个更新方法,它将使用该实例的pathData和pathIndex属性更新每帧的移动。

这是您可以用来实现目标的基本方法。