预加载后初始化资产

时间:2011-12-24 00:42:59

标签: actionscript-3 flash-cs5

每当我导出Flash游戏的.swf文件时,我都会收到"TypeError: Error #1009: Cannot access a property or method of a null object reference."以及Runtime Shared Library Preloading Warning的预加载器。我将时间轴组织起来,以便第一帧和第三帧都是空的,并在Actions层中使用stop();命令。第二帧包含一个MovieClip,其中包含我的所有导出资产,这些资产将在时间轴的第三帧中初始化。除了预加载器之外,我的所有资产都不会在第一帧中导出。我应该对文档类进行哪些更改,以便在第三帧中初始化资产?

文件类:

package com.gameEngine.documentClass
{
    import flash.events.*;
    import flash.display.*;
    import flash.geom.Point;
    import com.gameEngine.assetHolders.*;
    import com.gameEngine.assetHolders.Levels.*;

    public class Document extends MovieClip
    {
        private static var _document:Document;
        private var preloader:Preloader;
        public var mcMain:Player;
        public var restartButton:RestartButton;
        public var spawnArea:SpawnArea;
        public var level_1:Level_1;
        public var level_2:Level_2;
        public var level_3:Level_3;

        public function Document()
        {
            addEventListener(Event.ADDED_TO_STAGE, init);
            _document = this;
            preloader = new Preloader(390, this.loaderInfo);
            this.addChild(preloader);
            preloader.addEventListener("loadComplete", loadAssets);
            preloader.addEventListener("preloaderFinished", showLogo);
            mcMain = new Player(this);
            restartButton = new RestartButton(this);
            spawnArea = new SpawnArea();
            level_1 = new Level_1(this);
            level_2 = new Level_2(this);
            level_3 = new Level_3(this);
            this.addChild(restartButton);
            this.addChild(spawnArea);
            this.preloader.x = 400;
            this.preloader.y = 250;
            restartButton.x = 822.95;
            restartButton.y = 19;
            spawnArea.x = 400;
            spawnArea.y = 250;
            trace ("Document Class Initialized");
            // constructor code
        }
        public static function getInstance():Document
        {
            return _document;
        }
        private function loadAssets(event:Event):void
        {
            this.play();
        }
        private function showLogo(event:Event):void
        {
            this.removeChild(preloader);
        }
        public function init(event:Event)
        {
            if (stage.contains(spawnArea))
            {
                addChild(mcMain);
            }
            mcMain.x = spawnArea.x;
            mcMain.y = spawnArea.y;
        }
    }
}

预加载器类:

package com.gameEngine.assetHolders
{
    import com.gameEngine.documentClass.*;
    import flash.display.*;
    import flash.events.*;

    public class Preloader extends MovieClip
    {
        private var fullWidth:Number;
        public var loaderInfo:LoaderInfo;

        public function Preloader(fullWidth:Number = 0, loaderInfo:LoaderInfo = null)
        {
            this.fullWidth = fullWidth;
            this.loaderInfo = loaderInfo;

            addEventListener(Event.ENTER_FRAME, checkLoad);
        }

        private function checkLoad (event:Event):void
        {
            if (loaderInfo.bytesLoaded == loaderInfo.bytesTotal && loaderInfo.bytesTotal != 0)
            {
                dispatchEvent(new Event("loadComplete"));
                phaseOut();
            }

            updateLoader(loaderInfo.bytesLoaded / loaderInfo.bytesTotal);
        }

        private function updateLoader(num:Number):void
        {
            progressBar.width = num * fullWidth;
        }

        private function phaseOut():void
        {
            removeEventListener(Event.ENTER_FRAME, checkLoad);
            progressBar.gotoAndPlay(2);
            if (progressBar.currentFrame == progressBar.totalFrames)
            {
                phaseComplete();
            }
        }

        private function phaseComplete() : void
        {
            dispatchEvent(new Event("preloaderFinished"));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这里有很多竞争条件。许多这些事件可能在相对随机的时间相互发生。 。 。你必须异步思考。也就是说,任何对象都不存在假设。例如,在Document.init()中,您检查spawnArea是否存在,但几乎保证不会在那时,您再也不会检查它。

如果不做任何具体更改,我可以推荐一个通用的解决方案。对于要加载另一个对象(objB)后加载的任何对象(objA),请在objB的{​​{1}}处理程序中创建objA。一个简单的例子是:

ADDED_TO_STAGE

此时,它表明您需要规划对象创建的时间轴。