2014-03-06 49 views
0

我刚完成一个小游戏的基本结构和保存简单的预加载到最后。傻我。AS3 - 预载实施后引用舞台

许多教程后,我发现这一个为我工作 - Pre Loader in Flash Builder

预加载的作品,游戏是在舞台上,但瞬间冻结。任何在我的LevelOne代码中对阶段的引用都会引发错误。 错误#1009:无法访问空对象引用的属性或方法。

贯彻预载之前,我的应用程序类(RookiesGame)作为一个楼层切换。每个级别都包含在Sprite中。 RookiesGame开始加入LEVELONE至阶段,那么一旦玩家完成它,RookiesGame去除LEVELONE并添加LevelTwo至阶段等

水平的类引用阶段与_stage变量。

因为我一直都学习这种结构中,预加载器成为应用类别及RookiesGame刚刚成为另一个阶级真的搞糊涂了。不应该_stage var仍然工作?将RookiesGame作为关卡切换器可以吗?

反正主要问题是引用从水平分级阶段。

当前代码:

Preloader类

做工精细,游戏开始。

package 
{ 
    import flash.display.DisplayObject; 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 
    import flash.utils.getDefinitionByName; 

    [SWF(width="650", height="450", backgroundColor="#FFFFFF", frameRate="60")] 

    public class Preloader extends Sprite 
    { 
     // Private 
     private var _preloaderBackground:Shape 
     private var _preloaderPercent:Shape; 
     private var _checkForCacheFlag:Boolean = true; 
     // Constants 
     private static const MAIN_CLASS_NAME:String = "RookiesGame"; 

     public function Preloader() 
     { 
      trace("Preloader: Initialized.") 
      addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 
     } 

     public function dispose():void 
     { 
      trace("Preloader: Disposing.") 
      removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
      if (_preloaderBackground) 
      { 
       removeChild(_preloaderBackground); 
       _preloaderBackground = null; 
      } 
      if (_preloaderPercent) 
      { 
       removeChild(_preloaderPercent); 
       _preloaderPercent = null; 
      } 
     } 

     // Private functions 

     private function onAddedToStage(e:Event):void 
     { 
      trace("Preloader: Added to stage."); 
      removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 
      stage.scaleMode = StageScaleMode.SHOW_ALL; 
      stage.align = StageAlign.TOP_LEFT; 
      addEventListener(Event.ENTER_FRAME, onEnterFrame); 
     } 

     private function onEnterFrame(e:Event):void 
     { 
      if (_checkForCacheFlag == true) 
      { 
       _checkForCacheFlag = false; 
       if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal) 
       { 
        trace("Preloader: No need to load, all " + root.loaderInfo.bytesTotal + " bytes are cached."); 
        finishedLoading(); 
       } 
       else 
        beginLoading(); 
      } 
      else 
      { 
       if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal) 
       { 
        trace("Preloader: Finished loading all " + root.loaderInfo.bytesTotal + " bytes."); 
        finishedLoading(); 
       } 
       else 
       { 
        var percent:Number = root.loaderInfo.bytesLoaded/root.loaderInfo.bytesTotal; 
        updateGraphic(percent); 
        trace("Preloader: " + (percent * 100) + " %"); 
       } 
      } 
     } 

     private function beginLoading():void 
     { 
      // Might not be called if cached. 
      // ------------------------------ 
      trace("Preloader: Beginning loading.") 
      _preloaderBackground = new Shape() 
      _preloaderBackground.graphics.beginFill(0x333333) 
      _preloaderBackground.graphics.lineStyle(2,0x000000) 
      _preloaderBackground.graphics.drawRect(0,0,200,20) 
      _preloaderBackground.graphics.endFill() 

      _preloaderPercent = new Shape() 
      _preloaderPercent.graphics.beginFill(0xFFFFFFF) 
      _preloaderPercent.graphics.drawRect(0,0,200,20) 
      _preloaderPercent.graphics.endFill() 

      addChild(_preloaderBackground) 
      addChild(_preloaderPercent) 
      _preloaderBackground.x = _preloaderBackground.y = 10 
      _preloaderPercent.x = _preloaderPercent.y = 10 
      _preloaderPercent.scaleX = 0 
     } 

     private function updateGraphic(percent:Number):void 
     { 
      // Might not be called if cached. 
      // ------------------------------ 
      _preloaderPercent.scaleX = percent 
     } 

     private function finishedLoading():void 
     { 
      var RookiesGame:Class = getDefinitionByName(MAIN_CLASS_NAME) as Class; 

      if (RookiesGame == null) 
       throw new Error("Preloader: There is no class \"" + MAIN_CLASS_NAME + "\"."); 

      var main:DisplayObject = new RookiesGame() as DisplayObject; 
      if (main == null) 
       throw new Error("Preloader: The class \"" + MAIN_CLASS_NAME + "\" is not a Sprite or MovieClip."); 

      addChild(main); 
      dispose(); 
     } 
    } 
} 

RookiesGame类(以前是应用类)

的阶段的任何引用吐出来#1009错误,当我改变stage.addChild到 .addChild

,其停止

我还没有与preloader的水平转换处理程序,所以我不知道如何stage.focus也可以!

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

     public class RookiesGame extends Sprite 
     { 
      private var _levelOne:LevelOne; 
      private var _levelTwo:LevelTwo; 

       public function RookiesGame() 
       { 
       _levelOne = new LevelOne(stage); 
       _levelTwo = new LevelTwo(stage); 
       this.addChild(_levelOne); 
         this.addEventListener("levelOneComplete",levelTwoSwitchHandler);       
       } 
       private function levelTwoSwitchHandler(event:Event):void 
       { 
         this.removeChild(_levelOne); 
        _levelOne = null; 
        this.addChild(_levelTwo); 
         stage.focus = stage;    

       } 
      } 
} 

LEVELONE类

地段#1009错误。任何引用舞台的东西。

类是巨大的,所以我还是要强调的问题块。

引用阶段时,添加键盘监听器#1009错误。

_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); 
_stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 

另外#1009引用阶段时检查阶段边界。不能改变阶段。这个。了。

private function checkStageBoundaries(gameObject:MovieClip):void 
     { 
      if (gameObject.x < 50) 
      { 
       gameObject.x = 50; 
      } 
      if (gameObject.y < 50) 
      { 
       gameObject.y = 50; 
      } 
      if (gameObject.x + gameObject.width > _stage.stageWidth - 50) 
      { 
       gameObject.x = _stage.stageWidth - gameObject.width - 50; 
      } 
      if (gameObject.y + gameObject.height > _stage.stageHeight - 50) 
      { 
       gameObject.y = _stage.stageHeight - gameObject.height - 50; 
      } 
     } 

我引用_stage稍后在程序中删除事件侦听器。而已。

_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); 
_stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 

我该如何参考舞台,没有这些错误,并保持RookiesGame作为关卡切换器。

LEVELONE阶层结构

为了表明我如何使用(d)_stage。

package 
{ 
     //import classes 

     public class LevelOne extends Sprite 
     { 
     //Declare the variables to hold the game objects 

     //A variable to store the reference to the stage from the application class 
     private var _stage:Object; 


     public function LevelOne(stage:Object) 
      { 
       _stage = stage; 
       this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 
      } 
      private function addedToStageHandler(event:Event):void 
      { 
       startGame(); 
       this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 
      } 
      private function startGame():void 
      { 
      //Includes _stage references that mess everything up. 
      } 
      private function levelCleared():void 
      { 
      //When Level finished, dispatch event to tell RookiesGame to switch levels. 
      dispatchEvent(new Event("levelOneComplete", true)); 
      } 
    }   
} 

很抱歉,如果这就是困惑,但如果你能帮助我参考一下通过LEVELONE和RookiesGame类的阶段,这将是非常赞赏。

回答

0

您正在从RookiesGame类中传入空stageLevelOne。每当你实例化一个RookiesGame时,构造函数将首先运行,它还没有被添加到显示列表中,所以它继承的对stage的引用是null。你需要做的是在RookiesGame类添加的事件侦听器ADDED_TO_STAGE

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

    public class RookiesGame extends Sprite 
    { 
     private var _levelOne:LevelOne; 
     private var _levelTwo:LevelTwo; 

      public function RookiesGame() 
      { 
       addEventListener(Event.ADDED_TO_STAGE, onAdded);       
      } 
      //added to stage event 
      private function onAdded(e:Event):void { 
       removeEventListener(Event.ADDED_TO_STAGE, onAdded); 
       _levelOne = new LevelOne(stage); 
       _levelTwo = new LevelTwo(stage); 
       this.addChild(_levelOne); 
       this.addEventListener("levelOneComplete",levelTwoSwitchHandler); 
      } 

      ... 
     } 

此外,如果你正在使用addChild()呼吁LevelOneaddChild(_levelOne)它有自己的参考stage它被添加到显示后列表中,如果要将它们添加到显示列表中,则不需要为这些类创建_stage变量。

你也有LevelOne,为ADDED_TO_STAGE听者在stage变量将会不再是零,这样你就可以删除你的类变量_stage完全。

+0

非常感谢。你完全去除_stage变量也是正确的。我一直在学习的文本使用_stage var和ADDED_TO_STAGE?奇怪。再次感谢! – Rookie