1

谁能帮我理解以下内容?

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

  (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)));
    }
4

1 回答 1

1

您对两个不同的点感到困惑,但我认为它们都源于对 Flash 如何处理坐标系的不完整视图。回想一下,每个显示对象都带有自己的坐标系统。在您的第一个问题中,对象的“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 中的工作方式。阅读这篇优秀文章的前几段以了解总体思路,然后了解在此示例中事件最初是从一个矩形发出的(因为这是被点击的图形所在的位置),但您只能在它们冒泡时捕捉它们通过您设置侦听器的范围。矩形也是如此e.target,并且e.currentTarget是您的听众的范围。那么最后的难题是理解这一点e.localX,并且e.localY始终处于事件原始目标的坐标系中。(这是因为它们是事件的属性,当事件在显示列表中冒泡时,它们不断变化是没有意义的。)

最后一点,如果您想知道初学者通常如何处理这些东西,答案是人们通常将侦听器直接附加到具有将被单击的图形内容的显示对象上。在这种情况下,e.target 和 e.currentTarget 将始终相同,大多数初学者不需要了解这些。

于 2010-01-24T23:49:10.717 回答