守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 699|回复: 1

[算法/性能优化] line fastest a* search path A星寻路

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51782
    钢镚
    1422

    开源英雄守望者

    发表于 2015-7-15 14:25:18 | 显示全部楼层 |阅读模式




    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.     public class Game2 extends Sprite {
    24.         private var _cellSize:int = 5;
    25.         private var _grid:Grid;
    26.         private var _player:Sprite;
    27.         private var _index:int;
    28.         private var _path:Array;

    29.         private var tf:Label;
    30.         private var astar:AStar;

    31.         private var path:Sprite = new Sprite();
    32.         private var image:Bitmap = new Bitmap(new BitmapData(1, 1));
    33.         private var imageWrapper:Sprite = new Sprite();

    34.         public function Game2(){
    35.             stage.align = StageAlign.TOP_LEFT;
    36.             stage.scaleMode = StageScaleMode.NO_SCALE;
    37.             addChild(imageWrapper);
    38.             imageWrapper.addChild(image);
    39.             makePlayer();

    40.             var w:Window = new Window(this, 20, 20, "tool");
    41.             numCols = new LabelInput("numCols ", "numCols");
    42.             numCols.setValue("50");
    43.             w.add(numCols);
    44.             numRows = new LabelInput("numRows ", "numRows");
    45.             w.add(numRows);
    46.             numRows.setValue("50");
    47.             cellSize = new LabelInput("cellSize", "cellSize");
    48.             cellSize.setValue("10");
    49.             w.add(cellSize);
    50.             density = new LabelInput("density ", "density");
    51.             density.setValue("0.1");
    52.             w.add(density);
    53.             isEight = new Checkbox("是否8方向");
    54.             isEight.setToggle(true);
    55.             w.add(isEight);
    56.             tf = new Label("info");
    57.             w.add(tf);
    58.             w.add(new sliz.miniui.Link("author sliz"));
    59.             w.add(new sliz.miniui.Link("source", "http://code.google.com/p/actionscriptiui/"));
    60.             var btn:Button = new Button("新建", 0, 0, null, newMap);
    61.             w.add(btn, null, 0.8);
    62.             w.setLayout(new BoxLayout(w, 1, 5));
    63.             w.doLayout();
    64.             imageWrapper.addEventListener(MouseEvent.CLICK, onGridClick);
    65.             addEventListener(Event.ENTER_FRAME, onEnterFrame);
    66.             imageWrapper.addChild(path);
    67.             makeGrid();
    68.         }

    69.         private function newMap(e:Event):void {
    70.             makeGrid();
    71.         }

    72.         private function changeMode(e:Event):void {
    73.         /*if (_grid.getType()==1) {
    74.            _grid.calculateLinks(0);
    75.            (e.currentTarget as Button).text = "  四方向  ";
    76.            }else {
    77.            _grid.calculateLinks(1);
    78.            (e.currentTarget as Button).text = "  八方向  ";
    79.          }*/
    80.         }

    81.         private function makePlayer():void {
    82.             _player = new Sprite();
    83.             _player.graphics.beginFill(0xff00ff);
    84.             _player.graphics.drawCircle(0, 0, 2);
    85.             _player.graphics.endFill();
    86.             imageWrapper.addChild(_player);
    87.         }

    88.         private function makeGrid():void {
    89.             var rows:int = int(numRows.getValue());
    90.             var cols:int = int(numCols.getValue());
    91.             _cellSize = int(cellSize.getValue());
    92.             _grid = new Grid(cols, rows);
    93.             for (var i:int = 0; i < rows * cols * Number(density.getValue()); i++){
    94.                 _grid.setWalkable(Math.floor(Math.random() * cols), Math.floor(Math.random() * rows), false);
    95.             }
    96.             _grid.setWalkable(0, 0, true);
    97.             _grid.setWalkable(cols / 2, rows / 2, false);
    98.             if (isEight.getToggle())
    99.                 _grid.calculateLinks();
    100.             else
    101.                 _grid.calculateLinks(1);
    102.             astar = new AStar(_grid);
    103.             drawGrid();
    104.             isClick = false;
    105.             _player.x = 0;
    106.             _player.y = 0;
    107.             path.graphics.clear();
    108.         }


    109.         private function drawGrid():void {
    110.             image.bitmapData = new BitmapData(_grid.numCols * _cellSize, _grid.numRows * _cellSize, false, 0xffffff);
    111.             for (var i:int = 0; i < _grid.numCols; i++){
    112.                 for (var j:int = 0; j < _grid.numRows; j++){
    113.                     var node:Node = _grid.getNode(i, j);
    114.                     if (!node.walkable){
    115.                         image.bitmapData.fillRect(new Rectangle(i * _cellSize, j * _cellSize, _cellSize, _cellSize), getColor(node));
    116.                     }
    117.                 }
    118.             }
    119.         }

    120.         private function getColor(node:Node):uint {
    121.             if (!node.walkable)
    122.                 return 0;
    123.             if (node == _grid.startNode)
    124.                 return 0xcccccc;
    125.             if (node == _grid.endNode)
    126.                 return 0xcccccc;
    127.             return 0xffffff;
    128.         }

    129.         private function onGridClick(event:MouseEvent):void {
    130.             var xpos:int = Math.floor(mouseX / _cellSize);
    131.             var ypos:int = Math.floor(mouseY / _cellSize);
    132.             xpos = Math.min(xpos, _grid.numCols - 1);
    133.             ypos = Math.min(ypos, _grid.numRows - 1);
    134.             _grid.setEndNode(xpos, ypos);

    135.             xpos = Math.floor(_player.x / _cellSize);
    136.             ypos = Math.floor(_player.y / _cellSize);
    137.             _grid.setStartNode(xpos, ypos);
    138.             findPath();
    139.             //path.graphics.clear();
    140.             //path.graphics.lineStyle(0, 0xff0000,0.5);
    141.             //path.graphics.moveTo(_player.x, _player.y);
    142.         }

    143.         private function findPath():void {
    144.             var time:int = getTimer();
    145.             if (astar.findPath()){
    146.                 _index = 0;
    147.                 isClick = true;

    148.                 astar.floyd();
    149.                 _path = astar.floydPath;
    150.                 time = getTimer() - time;
    151.                 tf.text = time + "ms   length:" + astar.path.length;
    152.                 trace(astar.floydPath);
    153.                 path.graphics.clear();
    154.                 for (var i:int = 0; i < astar.floydPath.length; i++){
    155.                     var p:Node = astar.floydPath[i];
    156.                     path.graphics.lineStyle(0, 0xff0000);
    157.                     path.graphics.drawCircle((p.x + 0.5) * _cellSize, (p.y + 0.5) * _cellSize, 2);

    158.                     path.graphics.lineStyle(0, 0xff0000, 0.5);
    159.                     path.graphics.moveTo(_player.x, _player.y);
    160.                 }
    161.             } else {
    162.                 time = getTimer() - time;
    163.                 tf.text = time + "ms 找不到";
    164.             }
    165.         }

    166.         private var isClick:Boolean = false;
    167.         private var numCols:LabelInput;
    168.         private var numRows:LabelInput;
    169.         private var cellSize:LabelInput;
    170.         private var density:LabelInput;
    171.         private var isEight:Checkbox;

    172.         private function onEnterFrame(event:Event):void {
    173.             if (!isClick){
    174.                 return;
    175.             }
    176.             var targetX:Number = _path[_index].x * _cellSize + _cellSize / 2;
    177.             var targetY:Number = _path[_index].y * _cellSize + _cellSize / 2;
    178.             var dx:Number = targetX - _player.x;
    179.             var dy:Number = targetY - _player.y;
    180.             var dist:Number = Math.sqrt(dx * dx + dy * dy);
    181.             if (dist < 1){
    182.                 _index++;
    183.                 if (_index >= _path.length){
    184.                     isClick = false;
    185.                 }
    186.             } else {
    187.                 _player.x += dx * .5;
    188.                 _player.y += dy * .5;
    189.                 path.graphics.lineTo(_player.x, _player.y);
    190.             }
    191.         }
    192.     }
    193. }

    194. import flash.geom.Point;

    195. class AStar {
    196.     //private var _open:Array;
    197.     private var _open:BinaryHeap;
    198.     private var _grid:Grid;
    199.     private var _endNode:Node;
    200.     private var _startNode:Node;
    201.     private var _path:Array;
    202.     private var _floydPath:Array;
    203.     public var heuristic:Function;
    204.     private var _straightCost:Number = 1.0;
    205.     private var _diagCost:Number = Math.SQRT2;
    206.     private var nowversion:int = 1;

    207.     public function AStar(grid:Grid){
    208.         this._grid = grid;
    209.         heuristic = euclidian2;

    210.     }

    211.     private function justMin(x:Object, y:Object):Boolean {
    212.         return x.f < y.f;
    213.     }

    214.     public function findPath():Boolean {
    215.         _endNode = _grid.endNode;
    216.         nowversion++;
    217.         _startNode = _grid.startNode;
    218.         //_open = [];
    219.         _open = new BinaryHeap(justMin);
    220.         _startNode.g = 0;
    221.         return search();
    222.     }

    223.     public function floyd():void {
    224.         if (path == null)
    225.             return;
    226.         _floydPath = path.concat();
    227.         var len:int = _floydPath.length;
    228.         if (len > 2){
    229.             var vector:Node = new Node(0, 0);
    230.             var tempVector:Node = new Node(0, 0);
    231.             floydVector(vector, _floydPath[len - 1], _floydPath[len - 2]);
    232.             for (var i:int = _floydPath.length - 3; i >= 0; i--){
    233.                 floydVector(tempVector, _floydPath[i + 1], _floydPath[i]);
    234.                 if (vector.x == tempVector.x && vector.y == tempVector.y){
    235.                     _floydPath.splice(i + 1, 1);
    236.                 } else {
    237.                     vector.x = tempVector.x;
    238.                     vector.y = tempVector.y;
    239.                 }
    240.             }
    241.         }
    242.         len = _floydPath.length;
    243.         for (i = len - 1; i >= 0; i--){
    244.             for (var j:int = 0; j <= i - 2; j++){
    245.                 if (floydCrossAble(_floydPath[i], _floydPath[j])){
    246.                     for (var k:int = i - 1; k > j; k--){
    247.                         _floydPath.splice(k, 1);
    248.                     }
    249.                     i = j;
    250.                     len = _floydPath.length;
    251.                     break;
    252.                 }
    253.             }
    254.         }
    255.     }

    256.     private function floydCrossAble(n1:Node, n2:Node):Boolean {
    257.         var ps:Array = bresenhamNodes(new Point(n1.x, n1.y), new Point(n2.x, n2.y));
    258.         for (var i:int = ps.length - 2; i > 0; i--){
    259.             if (ps[i].x>=0&&ps[i].y>=0&&ps[i].x<_grid.numCols&&ps[i].y<_grid.numRows&&!_grid.getNode(ps[i].x,ps[i].y).walkable) {
    260.                 return false;
    261.             }
    262.         }
    263.         return true;
    264.     }

    265.     private function bresenhamNodes(p1:Point, p2:Point):Array {
    266.             var steep:Boolean = Math.abs(p2.y - p1.y) > Math.abs(p2.x - p1.x);
    267.             if (steep) {
    268.                 var temp:int = p1.x;
    269.                 p1.x = p1.y;
    270.                 p1.y = temp;
    271.                 temp = p2.x;
    272.                 p2.x = p2.y;
    273.                 p2.y = temp;
    274.             }
    275.             var stepX:int = p2.x > p1.x?1:(p2.x < p1.x? -1:0);
    276.             var deltay:Number = (p2.y - p1.y)/Math.abs(p2.x-p1.x);
    277.             var ret:Array = [];
    278.             var nowX:Number = p1.x + stepX;
    279.             var nowY:Number = p1.y + deltay;
    280.             if (steep) {
    281.                 ret.push(new Point(p1.y,p1.x));
    282.             }else {
    283.                 ret.push(new Point(p1.x,p1.y));
    284.             }
    285.             if (Math.abs(p1.x - p2.x) == Math.abs(p1.y - p2.y)) {
    286.                 if(p1.x<p2.x&&p1.y<p2.y){
    287.                     ret.push(new Point(p1.x, p1.y + 1), new Point(p2.x, p2.y - 1));
    288.                 }else if(p1.x>p2.x&&p1.y>p2.y){
    289.                     ret.push(new Point(p1.x, p1.y - 1), new Point(p2.x, p2.y + 1));
    290.                 }else if(p1.x<p2.x&&p1.y>p2.y){
    291.                     ret.push(new Point(p1.x, p1.y - 1), new Point(p2.x, p2.y + 1));
    292.                 }else if(p1.x>p2.x&&p1.y<p2.y){
    293.                     ret.push(new Point(p1.x, p1.y + 1), new Point(p2.x, p2.y - 1));
    294.                 }
    295.             }
    296.             while (nowX != p2.x) {
    297.                 var fy:int=Math.floor(nowY)
    298.                 var cy:int = Math.ceil(nowY);
    299.                 if (steep) {
    300.                     ret.push(new Point(fy, nowX));
    301.                 }else{
    302.                     ret.push(new Point(nowX, fy));
    303.                 }
    304.                 if (fy != cy) {
    305.                     if (steep) {
    306.                         ret.push(new Point(cy,nowX));
    307.                     }else{
    308.                         ret.push(new Point(nowX, cy));
    309.                     }
    310.                 }else if(deltay!=0){
    311.                     if (steep) {
    312.                         ret.push(new Point(cy+1,nowX));
    313.                         ret.push(new Point(cy-1,nowX));
    314.                     }else{
    315.                         ret.push(new Point(nowX, cy+1));
    316.                         ret.push(new Point(nowX, cy-1));
    317.                     }
    318.                 }
    319.                 nowX += stepX;
    320.                 nowY += deltay;
    321.             }
    322.             if (steep) {
    323.                 ret.push(new Point(p2.y,p2.x));
    324.             }else {
    325.                 ret.push(new Point(p2.x,p2.y));
    326.             }
    327.             return ret;
    328.         }
    329.     private function floydVector(target:Node, n1:Node, n2:Node):void {
    330.         target.x = n1.x - n2.x;
    331.         target.y = n1.y - n2.y;
    332.     }

    333.     public function search():Boolean {
    334.         var node:Node = _startNode;
    335.         node.version = nowversion;
    336.         while (node != _endNode){
    337.             var len:int = node.links.length;
    338.             for (var i:int = 0; i < len; i++){
    339.                 var test:Node = node.links[i].node;
    340.                 var cost:Number = node.links[i].cost;
    341.                 var g:Number = node.g + cost;
    342.                 var h:Number = heuristic(test);
    343.                 var f:Number = g + h;
    344.                 if (test.version == nowversion){
    345.                     if (test.f > f){
    346.                         test.f = f;
    347.                         test.g = g;
    348.                         test.h = h;
    349.                         test.parent = node;
    350.                     }
    351.                 } else {
    352.                     test.f = f;
    353.                     test.g = g;
    354.                     test.h = h;
    355.                     test.parent = node;
    356.                     _open.ins(test);
    357.                     test.version = nowversion;
    358.                 }

    359.             }
    360.             if (_open.a.length == 1){
    361.                 return false;
    362.             }
    363.             node = _open.pop() as Node;
    364.         }
    365.         buildPath();
    366.         return true;
    367.     }

    368.     private function buildPath():void {
    369.         _path = [];
    370.         var node:Node = _endNode;
    371.         _path.push(node);
    372.         while (node != _startNode){
    373.             node = node.parent;
    374.             _path.unshift(node);
    375.         }
    376.     }

    377.     public function get path():Array {
    378.         return _path;
    379.     }

    380.     public function get floydPath():Array {
    381.         return _floydPath;
    382.     }

    383.     public function manhattan(node:Node):Number {
    384.         return Math.abs(node.x - _endNode.x) + Math.abs(node.y - _endNode.y);
    385.     }

    386.     public function manhattan2(node:Node):Number {
    387.         var dx:Number = Math.abs(node.x - _endNode.x);
    388.         var dy:Number = Math.abs(node.y - _endNode.y);
    389.         return dx + dy + Math.abs(dx - dy) / 1000;
    390.     }

    391.     public function euclidian(node:Node):Number {
    392.         var dx:Number = node.x - _endNode.x;
    393.         var dy:Number = node.y - _endNode.y;
    394.         return Math.sqrt(dx * dx + dy * dy);
    395.     }

    396.     private var TwoOneTwoZero:Number = 2 * Math.cos(Math.PI / 3);

    397.     public function chineseCheckersEuclidian2(node:Node):Number {
    398.         var y:int = node.y / TwoOneTwoZero;
    399.         var x:int = node.x + node.y / 2;
    400.         var dx:Number = x - _endNode.x - _endNode.y / 2;
    401.         var dy:Number = y - _endNode.y / TwoOneTwoZero;
    402.         return sqrt(dx * dx + dy * dy);
    403.     }

    404.     private function sqrt(x:Number):Number {
    405.         return Math.sqrt(x);
    406.     }

    407.     public function euclidian2(node:Node):Number {
    408.         var dx:Number = node.x - _endNode.x;
    409.         var dy:Number = node.y - _endNode.y;
    410.         return dx * dx + dy * dy;
    411.     }

    412.     public function diagonal(node:Node):Number {
    413.         var dx:Number = Math.abs(node.x - _endNode.x);
    414.         var dy:Number = Math.abs(node.y - _endNode.y);
    415.         var diag:Number = Math.min(dx, dy);
    416.         var straight:Number = dx + dy;
    417.         return _diagCost * diag + _straightCost * (straight - 2 * diag);
    418.     }
    419. }


    420. class BinaryHeap {
    421.     public var a:Array = [];
    422.     public var justMinFun:Function = function(x:Object, y:Object):Boolean {
    423.         return x < y;
    424.     };

    425.     public function BinaryHeap(justMinFun:Function = null){
    426.         a.push(-1);
    427.         if (justMinFun != null)
    428.             this.justMinFun = justMinFun;
    429.     }

    430.     public function ins(value:Object):void {
    431.         var p:int = a.length;
    432.         a[p] = value;
    433.         var pp:int = p >> 1;
    434.         while (p > 1 && justMinFun(a[p], a[pp])){
    435.             var temp:Object = a[p];
    436.             a[p] = a[pp];
    437.             a[pp] = temp;
    438.             p = pp;
    439.             pp = p >> 1;
    440.         }
    441.     }

    442.     public function pop():Object {
    443.         var min:Object = a[1];
    444.         a[1] = a[a.length - 1];
    445.         a.pop();
    446.         var p:int = 1;
    447.         var l:int = a.length;
    448.         var sp1:int = p << 1;
    449.         var sp2:int = sp1 + 1;
    450.         while (sp1 < l){
    451.             if (sp2 < l){
    452.                 var minp:int = justMinFun(a[sp2], a[sp1]) ? sp2 : sp1;
    453.             } else {
    454.                 minp = sp1;
    455.             }
    456.             if (justMinFun(a[minp], a[p])){
    457.                 var temp:Object = a[p];
    458.                 a[p] = a[minp];
    459.                 a[minp] = temp;
    460.                 p = minp;
    461.                 sp1 = p << 1;
    462.                 sp2 = sp1 + 1;
    463.             } else {
    464.                 break;
    465.             }
    466.         }
    467.         return min;
    468.     }
    469. }

    470. class Grid {

    471.     private var _startNode:Node;
    472.     private var _endNode:Node;
    473.     private var _nodes:Array;
    474.     private var _numCols:int;
    475.     private var _numRows:int;

    476.     private var type:int;

    477.     private var _straightCost:Number = 1.0;
    478.     private var _diagCost:Number = Math.SQRT2;

    479.     public function Grid(numCols:int, numRows:int){
    480.         _numCols = numCols;
    481.         _numRows = numRows;
    482.         _nodes = new Array();

    483.         for (var i:int = 0; i < _numCols; i++){
    484.             _nodes[i] = new Array();
    485.             for (var j:int = 0; j < _numRows; j++){
    486.                 _nodes[i][j] = new Node(i, j);
    487.             }
    488.         }
    489.     }

    490.     /**
    491.      *
    492.      * @param    type    0四方向 1八方向 2跳棋
    493.      */
    494.     public function calculateLinks(type:int = 0):void {
    495.         this.type = type;
    496.         for (var i:int = 0; i < _numCols; i++){
    497.             for (var j:int = 0; j < _numRows; j++){
    498.                 initNodeLink(_nodes[i][j], type);
    499.             }
    500.         }
    501.     }

    502.     public function getType():int {
    503.         return type;
    504.     }

    505.     /**
    506.      *
    507.      * @param    node
    508.      * @param    type    0八方向 1四方向 2跳棋
    509.      */
    510.     private function initNodeLink(node:Node, type:int):void {
    511.         var startX:int = Math.max(0, node.x - 1);
    512.         var endX:int = Math.min(numCols - 1, node.x + 1);
    513.         var startY:int = Math.max(0, node.y - 1);
    514.         var endY:int = Math.min(numRows - 1, node.y + 1);
    515.         node.links = [];
    516.         for (var i:int = startX; i <= endX; i++){
    517.             for (var j:int = startY; j <= endY; j++){
    518.                 var test:Node = getNode(i, j);
    519.                 if (test == node || !test.walkable){
    520.                     continue;
    521.                 }
    522.                 if (type != 2 && i != node.x && j != node.y){
    523.                     var test2:Node = getNode(node.x, j);
    524.                     if (!test2.walkable){
    525.                         continue;
    526.                     }
    527.                     test2 = getNode(i, node.y);
    528.                     if (!test2.walkable){
    529.                         continue;
    530.                     }
    531.                 }
    532.                 var cost:Number = _straightCost;
    533.                 if (!((node.x == test.x) || (node.y == test.y))){
    534.                     if (type == 1){
    535.                         continue;
    536.                     }
    537.                     if (type == 2 && (node.x - test.x) * (node.y - test.y) == 1){
    538.                         continue;
    539.                     }
    540.                     if (type == 2){
    541.                         cost = _straightCost;
    542.                     } else {
    543.                         cost = _diagCost;
    544.                     }
    545.                 }
    546.                 node.links.push(new Link(test, cost));
    547.             }
    548.         }
    549.     }

    550.     public function getNode(x:int, y:int):Node {
    551.         return _nodes[x][y];
    552.     }

    553.     public function setEndNode(x:int, y:int):void {
    554.         _endNode = _nodes[x][y];
    555.     }

    556.     public function setStartNode(x:int, y:int):void {
    557.         _startNode = _nodes[x][y];
    558.     }

    559.     public function setWalkable(x:int, y:int, value:Boolean):void {
    560.         _nodes[x][y].walkable = value;
    561.     }

    562.     public function get endNode():Node {
    563.         return _endNode;
    564.     }

    565.     public function get numCols():int {
    566.         return _numCols;
    567.     }

    568.     public function get numRows():int {
    569.         return _numRows;
    570.     }

    571.     public function get startNode():Node {
    572.         return _startNode;
    573.     }

    574. }

    575. class Link {
    576.     public var node:Node;
    577.     public var cost:Number;

    578.     public function Link(node:Node, cost:Number){
    579.         this.node = node;
    580.         this.cost = cost;
    581.     }

    582. }

    583. class Node {
    584.     public var x:int;
    585.     public var y:int;
    586.     public var f:Number;
    587.     public var g:Number;
    588.     public var h:Number;
    589.     public var walkable:Boolean = true;
    590.     public var parent:Node;
    591.     //public var costMultiplier:Number = 1.0;
    592.     public var version:int = 1;
    593.     public var links:Array;

    594.     //public var index:int;
    595.     public function Node(x:int, y:int){
    596.         this.x = x;
    597.         this.y = y;
    598.     }

    599.     public function toString():String {
    600.         return "x:" + x + " y:" + y;
    601.     }
    602. }
    复制代码






    本文来自:http://wonderfl.net/c/aWCe

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-2-24 01:34
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    0

    主题

    38

    帖子

    868

    积分

    上士

    Rank: 5Rank: 5

    威望
    20
    贡献
    0
    金币
    14
    钢镚
    0
    发表于 2019-2-24 02:30:51 | 显示全部楼层
    感谢分享!~
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-11-13 10:18 , Processed in 0.068572 second(s), 34 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表