如何在 as3 中使用 getChildIndex 设置 public 变量?

How can I set a public variable using getChildIndex in as3?

我正在编写一个非常简单的程序,让您可以围绕一个圆圈移动,舞台上还有一个矩形。我想让圆圈在拖动时位于矩形前面,但是当您释放鼠标时,圆圈会被送回。

我不知道如何使用 getChildIndex 方法设置 public 变量。我真的不关心其余的代码。我主要感兴趣的是如何使 getChildIndex 方法与 public 变量一起使用。

package code
{

    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.Sprite;


    public class Main extends MovieClip
    {           
        public var myCircleIndex:int = getChildIndex(myCircle);

        public function Main()
        {
            myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
        }

        public function mouseClicking(e:MouseEvent): void
        {
            myCircle.startDrag();
            setChildIndex(myCircle, numChildren-1);
        }

        public function mouseReleased(e:MouseEvent): void
        {
            myCircle.stopDrag();
            setChildIndex(myCircle, myCircleIndex);
        }
    }
}

我正在使用直接在舞台上创建的实例 ("myCircle") 作为影片剪辑。

问题出在我一开始设置的 public var 中,它不让我获取 myCircle 的子索引,但是如果我将同一行放在一个函数中,它就可以工作。
我知道我可以直接将 myCircle 的索引号放在最后一行(并删除 public var myCircleIndex),但我发现有一种方法可以将 getChildIndex 用于 public var在 class 中。

如何在 class 内的 public 变量中使用 getChildIndex?

将圆圈放在正方形后面所需要做的就是发布 addChild(myRectangle)addChildAt(myCircle, 0);

在我看来,您试图跟踪变量会使事情过于复杂。让 flash 在幕后解决它。

如果你想要更精细一点,只想把圆圈直接放在正方形后面(如果有100层,正方形在第12层,但你不确定正方形在第几层)你可以

addChildAt(myCircle, getChildIndex(myRectangle)-1);

setChildIndex(myCircle, numChildren-1);

这样做很好。更常见的方法是

addChild(myCircle);

它做的事情完全一样。许多人对此感到困惑,认为这会添加一个新的 myCircle 但如果它已经在显示列表中,它只是将它带到前面,如果它不在显示列表中,它会将它添加到显示列表中最高 z 顺序 (numChildren-1).

它不起作用的原因是,当 public var myCircleIndex:int 行运行时,您的时间轴对象尚不存在。

出于这个原因,您不应该尝试访问 class 级别变量声明中的非基本对象,因为在创建这些变量时,class 中的其他内容尚不可用。

重构方法如下(参见代码注释):

public class Main extends MovieClip
{           
    public var myCircleIndex:int;  //just create the reference here, don't assign it
    public var myCircle:flash.display.DisplayObject; //this line is just for better compile time checking and code completion, completely optional

    public function Main()
    {
        //wait for all the display stuff to be created before trying to access it.  The constructor function can run before timeline stuff is created, so it's not safe to reference stage or timeline objects here. 
        if(!stage){
            this.addEventListener(Event.ADDED_TO_STAGE, timelineCreated);
        }else {
            timelineCreated(null);
        }
    }

    private function timelineCreated(e:Event):void {
        //now that we're certain the timeline stuff has been created, we can reference timeline objects and stage:

        //store the initial z-index of myCircle
        myCircleIndex = getChildIndex(myCircle);

        //the rest of your code that was in the construction -Main()- before
        myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
        stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
    }

    //no change to any of the following stuff

    public function mouseClicking(e:MouseEvent): void
    {
        myCircle.startDrag();
        setChildIndex(myCircle, numChildren-1);
    }

    public function mouseReleased(e:MouseEvent): void
    {
        myCircle.stopDrag();
        setChildIndex(myCircle, myCircleIndex);
    }
}