仅在第 2 帧出现错误 #1009

Error #1009 only on frame 2

它突出显示该部分的第二行并表示无法访问空对象,但只能在第二帧上访问 如果在主文档上我将它设置为转到第 1 帧它工作完美 char 由 child

添加

地块class

package  
{
    import flash.display.MovieClip;
    import flash.events.Event;

    public class Ground_1 extends MovieClip 
    {
        public function Ground_1() 
        {
            //constructor code
            trace(root);
            this.addEventListener(Event.ENTER_FRAME, loop);
        }
        function loop(e:Event)
        {
            //loop
            if(!root)
            {
                return;
            }
            for(var i:int=0;i<10;i++)
            {
                //solid ground
                trace("Char :", Main(root).char);

                if(this.hitTestPoint(MovieClip(root).char.x,MovieClip(root).char.y,true))
                {
                    MovieClip(root).char.y --;
                    MovieClip(root).char.Yvelocity = 0;
                    MovieClip(root).char.canJump = true;
                }
                //Cieling
                if(this.hitTestPoint(MovieClip(root).char.x,MovieClip(root).char.y-25,true))
                {
                    MovieClip(root).upPressed = false;
                    MovieClip(root).char.Yvelocity = 0;
                    MovieClip(root).char.y ++;
                }
                //Walls
                if(this.hitTestPoint(MovieClip(root).char.x+MovieClip(root).char.width/2,MovieClip(root).char.y-21,true))
                {
                    if(MovieClip(root).rightPressed)
                    {
                        MovieClip(root).rightPressed = false;
                        MovieClip(root).char.x -= MovieClip(root).char.speed;
                    }
                }
                else if(this.hitTestPoint(MovieClip(root).char.x-MovieClip(root).char.width/2,MovieClip(root).char.y-21,true))
                {
                    if(MovieClip(root).leftPressed)
                    {
                        MovieClip(root).leftPressed = false;
                        MovieClip(root).char.x += MovieClip(root).char.speed;
                    }
                }
            }
        }
    }   
}

主文档

package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;

    public class Main extends MovieClip
    {
        //KeyPressed
        var upPressed:Boolean = false;
        var downPressed:Boolean = false;
        var rightPressed:Boolean = false;
        var leftPressed:Boolean = false;
        var rPressed:Boolean = false;

        var char:player;

        public function Main()
        {
            //constructor code
            this.gotoAndStop(1);
            //Character
            char = new player();
            char.x = starter.x;
            char.y = starter.y;
            addChild(char);
            //starter
            starter.visible = false;
            //Event Listeners
            this.addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, downHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, upHandler);
        }
        function loop(e:Event)
        {
            //loop

            //cam
            Cam.y = char.y-50
            Cam.x = char.x
            Cam.visible = false;

            //Restart
            if(rPressed)
            {
                char.x = starter.x;
                char.y = starter.y;
                char.scaleX = 1;
                char.health = 6;
                trace("Restart");
                rPressed = false;
            }
        }
        function downHandler(e:KeyboardEvent)
        {
            //down
            if(e.keyCode == Keyboard.UP)
            {
                upPressed = true;
            }
            if(e.keyCode == Keyboard.DOWN)
            {
                downPressed = true;
            }
            if(e.keyCode == Keyboard.RIGHT)
            {
                rightPressed = true;
            }
            if(e.keyCode == Keyboard.LEFT)
            {
                leftPressed = true;
            }
            if(e.keyCode == Keyboard.R)
            {
                rPressed = true;
            }
        }
        function upHandler(e:KeyboardEvent)
        {
            //up
            if(e.keyCode == Keyboard.UP)
            {
                upPressed = false;
            }
            if(e.keyCode == Keyboard.DOWN)
            {
                downPressed = false;
            }
            if(e.keyCode == Keyboard.RIGHT)
            {
                rightPressed = false;
            }
            if(e.keyCode == Keyboard.LEFT)
            {
                leftPressed = false;
            }
            if(e.keyCode == Keyboard.R)
            {
                rPressed = false;
            }
        }
    }
}

您的问题是 root 在您的 Ground_1 个实例中的 loop 函数 运行 第一次为 null。

显示对象的 rootparentstage 变量仅在将显示对象添加到显示列表时才会填充。在 root & stage 的情况下,还必须添加父级(和任何祖父级),以便最顶层 parent/grandparent 是阶段本身。

在文档 class 中,不能保证在它的构造函数(函数 Main)中它已经在显示列表中。有时(通常)阶段在文档 class 构造函数中有值,但并非总是如此。

以下是您的代码如何执行的示例:

  1. 程序开始

  2. 文档Class构造函数运行s(主函数)

  3. 您的文档 class 时间线对象被实例化(这是它们的构造函数 运行

  4. 您的文档时间线对象已添加到显示列表

  5. 您的时间轴对象第一帧是运行

异步地,在#1 之后和#4 之前的某个时间,文档 class 被添加到舞台上。由于您在 Ground_1 构造函数中开始监听 ENTER_FRAME,因此不能保证 stage/root 可用。

因此,您需要等到安全时再监听 Event.ADDED_TO_STAGE 事件。

public function Main(){
    //if stage doesn't exist yet, wait for it, then call stageReady
    if(!stage){
        this.addEventListener(Event.ADDED_TO_STAGE, stageReady);
    }else{
        stageReady();
    }
}

private function stageReady(e:Event = null):void {
        this.gotoAndStop(1);
        //Character
        char = new player();
        char.x = starter.x;
        char.y = starter.y;
        addChild(char);
        //starter
        starter.visible = false;
        //Event Listeners
        this.addEventListener(Event.ENTER_FRAME, loop);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, downHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, upHandler);
}

同样,在您的 Ground_1 class 中,您也需要这样做:

public function Ground_1() 
{
        //constructor code
        trace(root); //likely null

        this.addEventListener(Event.ADDED_TO_STAGE, stageReady, false, 0, true);
        this.addEventListener(Event.REMOVED_FROM_STAGE, stageUnloaded, false, 0, true); //this is optional

        this.addEventListener(Event.ENTER_FRAME, loop);
}

private function stageReady(e:Event):void {
    //only listen for frame events once this object has been added to the stage
    this.addEventListener(Event.ENTER_FRAME, loop);
}

private function stageUnloaded(e:Event):void {
    //stop listening for frame events if this object gets removed from the stage
    this.removeEventListener(Event.ENTER_FRAME, loop);
}