2014-03-06 129 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