• actionscript中的简单寻路《修改版》


      1 package
    2 {
    3 import flash.display.Sprite;
    4 import flash.events.MouseEvent;
    5 import flash.utils.clearInterval;
    6 import flash.utils.getTimer;
    7 import flash.utils.setInterval;
    8
    9 [SWF(width='600',height='600',frameRate=24)]
    10 public class Astar extends Sprite
    11 {
    12 private var openList:Array = [];//开放列表
    13 private var closeList:Object = {};//关闭列表
    14 private var hGridCount:Number = 60;//横向网格数量
    15 private var vGridCount:Number = 60;//水平网格数量
    16 private var GridWidth:Number = 10;//网格的宽度
    17 private var BlockCount:int = 512;
    18 private var coordinate:Array;//全局坐标(网格坐标);
    19 private var tx:int;//目标x坐标点;
    20 private var ty:int;//目标y坐标点;
    21 private var nx:int;//当前x坐标点;
    22 private var ny:int;//当前Y坐标点;
    23 private var scene:Sprite;//场景
    24 private var player:Sprite;//控制对象
    25 private var block:Sprite;//障碍物
    26 private var path:Vector.<Object> = new Vector.<Object>();//行走路径
    27 private var node:Object = {};//父节点
    28 private var InID:int = 0;//intervalID
    29
    30 public function Astar()
    31 {
    32 _createScene();
    33 _initCoordinate();
    34 _createBlock();
    35 _createPlayer();
    36 stage.addEventListener(MouseEvent.CLICK,onClick);
    37 }
    38 /**
    39 * 创建场景格子
    40 *
    41 */
    42 private function _createScene():void
    43 {
    44 scene = new Sprite();
    45 this.addChild(scene);
    46 scene.graphics.clear();
    47 scene.graphics.beginFill(0xffffff);
    48 scene.graphics.lineStyle(1,0xcccccc);
    49 for(var i:int = 0;i < hGridCount;i++)
    50 {
    51 scene.graphics.moveTo(i*GridWidth,0);
    52 scene.graphics.lineTo(i*GridWidth,vGridCount*GridWidth);
    53 }
    54 for(i = 0;i < vGridCount;i++)
    55 {
    56 scene.graphics.moveTo(0,i*GridWidth);
    57 scene.graphics.lineTo(hGridCount*GridWidth,i*GridWidth);
    58 }
    59 scene.graphics.endFill();
    60 }
    61 /**
    62 * 初始化全局坐标 (网格坐标)
    63 *
    64 */
    65 private function _initCoordinate():void
    66 {
    67 coordinate = [];
    68 for (var i:int=0; i<hGridCount; i++)
    69 {
    70 coordinate.push([vGridCount]);
    71 for (var j:int=0; j<vGridCount; j++)
    72 {
    73 coordinate[i][j] =true;//true为可行走点
    74 }
    75 }
    76 }
    77 /**
    78 * 创建随机障碍物
    79 *
    80 */
    81 private function _createBlock():void
    82 {
    83 block = new Sprite();
    84 this.addChild(block);
    85 block.graphics.clear();
    86 block.graphics.beginFill(0x00ff00);
    87 for(var i:int = 0;i < BlockCount;i++)
    88 {
    89 var bx:Number = int(vGridCount * Math.random());
    90 var by:Number = int(hGridCount * Math.random());
    91
    92 block.graphics.drawRect(bx*GridWidth,by*GridWidth,GridWidth,GridWidth);
    93 coordinate[bx][by] = false;
    94 }
    95 block.graphics.endFill();
    96 }
    97 /**
    98 * 创建控制对象
    99 *
    100 */
    101 private function _createPlayer():void
    102 {
    103 nx = int(Math.random() * hGridCount);//宽度范围内随机X坐标;
    104 ny = int(Math.random() * vGridCount);//高度范围内随机Y坐标;
    105 //判断坐标上是否有障碍物
    106 if (!coordinate[nx][ny])
    107 _createPlayer();//如有障碍物重新再来
    108 else
    109 {
    110 player = new Sprite();
    111 addChild(player);
    112 player.graphics.beginFill(0x0000ff,1);
    113 player.graphics.lineStyle(1,0x000000);
    114 player.graphics.drawRect(0,0,GridWidth,GridWidth);
    115 player.graphics.endFill();
    116 player.x = nx * GridWidth;
    117 player.y = ny * GridWidth;
    118 }
    119 }
    120
    121 private function onClick(e:MouseEvent):void
    122 {
    123 //目标点的坐标
    124 tx = int(e.localX / GridWidth);
    125 ty = int(e.localY / GridWidth);
    126 //判断目标点是否障碍物;
    127 if(coordinate[tx][ty])
    128 {
    129 path = new Vector.<Object>();//初始化路径
    130 //获取开始点的坐标;
    131 nx = player.x/GridWidth;
    132 ny = player.y/GridWidth;
    133 //初始化
    134 node = {};//节点
    135 closeList = {}; //关闭列表
    136 openList = [];//开放列表;
    137
    138 seekRoad();
    139 InID = setInterval(walk,50);
    140 }
    141 else
    142 trace("目标点不可到达");
    143 }
    144
    145 private function seekRoad():void
    146 {
    147 //创建开始节点
    148 node = createNode(nx,ny,0,null);
    149 //把开始节放入关闭列表;
    150 closeList[node.nx + "_" + node.ny] = node;
    151 //开始循环;有两种情况退出循环:一是找到目标点,另一种是控制对象本身就在死角无法达到目标点
    152 while (true)
    153 {
    154 if (nx == tx && ny == ty)
    155 { //循环取父节点;
    156 while(node!=null){
    157 //把节点加入到路径
    158 path.push(node);
    159 //取父节点
    160 node = node.pNode;
    161 }
    162 //退出循环;
    163 break;
    164 }
    165 //创建八方向节点加入到开放列表;
    166 pushOpenList(createNode(nx ,ny+1,10,node));//
    167 pushOpenList(createNode(nx-1,ny+1,14,node));//左下
    168 pushOpenList(createNode(nx-1,ny ,10,node));//
    169 pushOpenList(createNode(nx-1,ny-1,14,node));//左上
    170 pushOpenList(createNode(nx ,ny-1,10,node));//
    171 pushOpenList(createNode(nx+1,ny-1,14,node));//右上
    172 pushOpenList(createNode(nx+1,ny ,10,node));//
    173 pushOpenList(createNode(nx+1,ny+1,14,node));//右下
    174 //如果开放列表为空,退出循环,说明本身就在死角里面
    175 if (openList.length == 0)
    176 break;
    177 //排序取出f值最小的节点;
    178 openList.sortOn("f",Array.NUMERIC);
    179 node = openList.shift();
    180 //把当前节点坐标设为下次循环的开始点坐标;
    181 nx = node.nx;
    182 ny = node.ny;
    183 closeList[node.nx + "_" + node.ny] = node;//把节点放到关闭列表;
    184 }
    185
    186 path.reverse(); //倒序排列
    187 //清空释放内存;
    188 node = null;
    189 closeList = null;
    190 openList = null;
    191 }
    192 /**
    193 * 加入开放列表
    194 * @param nd
    195 * @return
    196 *
    197 */
    198 private function pushOpenList(nd:Object):void
    199 {
    200 if (nd != null)
    201 {
    202 openList.push(nd);
    203 openList[nd.nx+"_"+nd.ny] = nd;
    204 }
    205 }
    206
    207 private function createNode(ix:int,iy:int,ng:int,pnd:Object):Object
    208 {
    209 //判断是否出格,是否障碍物,是否关闭或已开启;
    210 if (ix < 0 || iy < 0 || ix >= hGridCount || iy >= vGridCount || !coordinate[ix][iy]|| closeList[ix + "_" + iy]||openList[ix+"_"+iy])
    211 return null;
    212
    213 var node:Object = {};
    214 node.h = (Math.abs(tx-ix)+Math.abs(ty-iy))*10;
    215 if(pnd)
    216 {
    217 //判断走斜角时上下左右是否有障碍物;
    218 if(ng == 14)
    219 if(!coordinate[pnd.nx][iy]||!coordinate[ix][pnd.ny])
    220 return null
    221 node.g = ng + pnd.g;
    222 node.f = node.g + node.h;
    223 }
    224 else
    225 {
    226 node.g = 0;
    227 node.h = 0;
    228 node.f = 0
    229 }
    230
    231 node.nx = ix;
    232 node.ny = iy;
    233 node.pNode = pnd;
    234
    235 return node;
    236 }
    237
    238 private function walk():void
    239 {
    240 if (path.length == 0)
    241 clearInterval(InID);
    242 else
    243 {
    244 var obj:Object = path.shift();
    245 player.x = obj.nx * GridWidth;
    246 player.y = obj.ny * GridWidth;
    247 obj = null
    248 }
    249 }
    250 }
    251 }

    修改自:http://bbs.9ria.com/thread-84171-1-1.html

    主要做了一些精简并稍做优化,添加了少许注释,以后会详细写一篇帖子来讲解这段代码。

  • 相关阅读:
    Vue Router路由组件传参
    Object.defineProperty()详解
    响应状态码
    ngnix端口转发
    查看端口占用情况
    nginx的查看、启动、停止、重载命令
    nginx的几个默认路径
    pm2的一些常用命令
    为什么要学习HTML?HTML会过时吗?
    48.MySQL数据库使用(二)
  • 原文地址:https://www.cnblogs.com/crkay/p/2259292.html
Copyright © 2020-2023  润新知