调用removeChild后的Actionscript奇怪的coords

时间:2010-01-24 20:10:58

标签: flash actionscript coordinates sprite removechild

任何人都可以帮助我理解以下内容吗?

我创建了几个平方精灵然后删除第一个精灵 并显示坐标。 结果是:

  (x=0, y=0, w=208, h=40) 0 208
  (x=42, y=0, w=166, h=40) 0 166

虽然宽度已经改变,但x坐标仍为0, getBounds显示正确的值。 我希望x也会改变。 由于x的值错误,globalToLocal和localToGlobal工作不正确。

如果单击第二个(仍然可见)矩形左侧的某个位置 你得到:

2 28 (x=2, y=28)

这对什么都没有好处。括号中的值应该是阶段坐标,而不是。

代码:

    public function test():void {
        var s:Sprite;
        var i:int;

        var arr:Array = new Array();
        for (i = 0; i < 5; ++i)
        {
            s = new Sprite();
            s.graphics.beginFill(0x999);
            s.graphics.drawRect(0, 0, 40, 40);
            s.graphics.endFill();
            s.x = i * 42;
            arr.push(s);
            addChild(s);
        }
        trace(this.getBounds(stage), x, width);
        removeChild(arr[0]); arr[0] = null;
        trace(this.getBounds(stage), x, width);
        addEventListener(MouseEvent.CLICK, click);
    }

    private function click(e:MouseEvent):void {
        trace(e.localX, e.localY, localToGlobal(new Point(e.localX, e.localY)));
    }

1 个答案:

答案 0 :(得分:1)

你在两个不同的点上感到困惑,但我认为它们都源于对Flash如何处理坐标系的不完整视图。回想一下,每个显示对象都带有自己的coord系统。在第一个问题中,对象的“x”和“y”属性不是动态计算的,以反映对象的左上角,它们只是表示该对象的原点相对于其父坐标系的位置。因此,对象的“x”值不会因为对象的内容发生变化而改变 - 当您移动对象本身时它会发生变化。

舞台坐标的问题在于localToGlobal方法会从调用它的范围转换坐标 - 而你是从矩形的父节点调用它,但是你从中传递了坐标。矩形内的本地系统。注意跟随一点,它应该是有道理的:

function click(e:MouseEvent):void {
    // bad - uses rectangle coords in scope of "this"
    //trace(e.localX, e.localY, localToGlobal(new Point(e.localX, e.localY)));
    // works - call localToGlobal from the scope of the rectangle
    trace( e.target.localToGlobal(new Point(e.localX, e.localY)));
    // alternately, call it from any scope with coordinates taken from that scope:
    trace( localToGlobal( new Point( mouseX, mouseY )));
    trace( e.target.localToGlobal( new Point( e.target.mouseX, e.target.mouseY )));
}

<强>更新 令人困惑的部分原因是事件冒泡在AS3中如何工作。阅读this excellent article的前几段以获得一般性的想法,然后理解在这个例子中,事件最初是从一个矩形发出的(因为这是点击的图形所在的位置),但是你只能将它们捕获为它们会在您设置监听器的范围内冒泡。因此e.target是矩形,e.currentTarget是监听器的范围。然后,最后一个难题是要了解e.localXe.localY始终位于事件原始目标的坐标系中。 (这是因为它们是事件的属性,当事件冒出显示列表时,它们不断变化是不合理的。)

最后请注意,如果您想知道初学者通常如何处理这些问题,答案是人们通常会将监听器直接连接到具有将被点击的图形内容的显示对象。在这种情况下,e.target和e.currentTarget将始终相同,大多数初学者将不需要了解任何此类内容。