2014-06-19 157 views
0

我遇到了一個問題,我的按鈕只能工作一次。該按鈕觸發自定義事件。自定義事件觸發,並且我的DocumentClass上的一個偵聽器第一次拾取它,但之後沒有任何響應。按鈕只能工作一次

複製 Click Here,然後點擊「開始遊戲」,然後選擇菜單按鈕,右上角,然後單擊主菜單,然後點擊「開始遊戲」,然後選擇菜單鍵右上方,然後發現你不能再點擊主菜單。這是我的問題。它應該繼續工作。

DocumentClass添加了子openScreen。 openScreen觸發DocumentClass事件來添加子PlayScreen並移除openScreen。當點擊playScreen上的菜單按鈕時,屏幕會添加子菜單。 **單擊主菜單按鈕時,會觸發由DocumentClass偵聽的事件。觸發的功能將刪除playScreen並添加一個打開的屏幕。這一系列事件只有在**步驟掛斷之前才能完全工作。

文檔類

public class DocumentClass extends MovieClip 
{ 
    public var playScreen:PlayScreen = new PlayScreen(); 
    public var openScreen:OpenScreen = new OpenScreen(); 
    public var started:Boolean = false;  

    public function DocumentClass() 
    { 
     openScreen.addEventListener(GameEvent.STAR, OnPlayClick); 
     playScreen.addEventListener(GameEvent.NG, NewGame); 
     playScreen.menuScreen.addEventListener(GameEvent.NG, NewGame, true, 0, true); 
     playScreen.menuScreen.addEventListener(GameEvent.MM, onMain); 
     addChild(openScreen) 


    } 

    public function OnPlayClick(gameEvent:GameEvent):void{ 
     trace("start") 

     addChildAt(playScreen,0) 
     var tweenX:Tween = new Tween(openScreen, "x", None.easeIn, 0, -480, .5, true); 
     tweenX.addEventListener(TweenEvent.MOTION_FINISH, onTweenDone); 


    } 
    public function NewGame(gameEvent:GameEvent):void{ 
     removeChild(playScreen) 
     playScreen = new PlayScreen(); 
     addChild(playScreen) 
     playScreen.begin() 
    } 
    public function onMain(gameEvent:GameEvent):void{ 
     playScreen.removeChild(playScreen.menuScreen) 
     this.removeChild(playScreen) 
     //openScreen = new OpenScreen(); 
     openScreen.x = 0 
     addChild(openScreen) 
     playScreen = new PlayScreen(); 

MenuScreen 公共類MenuScreen擴展影片剪輯 {

public function MenuScreen() 
    { 
     backButton.buttonMode = true 
     backButton.addEventListener(MouseEvent.CLICK, OnBackClick); 

     exitButton.buttonMode = true 
     exitButton.addEventListener(MouseEvent.CLICK, OnExitClick); 

     restartButton.buttonMode = true 
     restartButton.addEventListener(MouseEvent.CLICK, OnRestartClick); 

     mainButton.buttonMode = true 
     mainButton.addEventListener(MouseEvent.CLICK, OnMainClick); 

     //NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, onSystemKey); 

     backButton.AnswerText.text = "Return to Game" 
     restartButton.AnswerText.text = "Restart" 
     mainButton.AnswerText.text = "Main Menu" 
     exitButton.AnswerText.text = "Exit" 
    } 

    public function OnBackClick(myEvent:MouseEvent):void{ 
     this.dispatchEvent(new GameEvent(GameEvent.BAC)) 

    } 
    public function OnExitClick(myEvent:MouseEvent):void{ 
     //NativeApplication.nativeApplication.exit(); 

    } 
    public function OnRestartClick(myEvent:MouseEvent):void{ 
     this.dispatchEvent(new GameEvent(GameEvent.NG)) 
     trace("restrt click") 
    } 
    public function OnMainClick(myEvent:MouseEvent):void{ 
     this.dispatchEvent(new GameEvent(GameEvent.MM)) 
     trace("main click") 
    } 

    protected function onSystemKey(e:KeyboardEvent):void 
    { 
     if(e.keyCode == Keyboard.BACK) 
     { 
      e.preventDefault(); 
      this.dispatchEvent(new GameEvent(GameEvent.BAC)) 
     } 
     else if(e.keyCode == Keyboard.HOME) 
     { 
      //handle the button press here. 
     } 
     else if(e.keyCode == Keyboard.MENU) 
     { 
      //handle the button press here. 
     } 
    } 


} 

OpenScreen

public class OpenScreen extends MovieClip 
{ 

    public var hs:String 

    public function OpenScreen() 
    { 
     startButton.buttonMode = true 
     startButton.addEventListener(MouseEvent.CLICK, OnStartClick); 

     exitButton.buttonMode = true 
     exitButton.addEventListener(MouseEvent.CLICK, OnExitClick); 


     //NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, onSystemKey); 
     readObject() 
     highScoreText.text = String(hs) 
     trace(highScoreText.text) 
     startButton.AnswerText.text = "Start" 
     //restartButton.AnswerText.text = "Restart" 
     //mainButton.AnswerText.text = "Main Menu" 
     exitButton.AnswerText.text = "Exit" 
    } 

    public function OnStartClick(myEvent:MouseEvent):void{ 
     trace(this.hasEventListener(GameEvent.STAR)) 
     this.dispatchEvent(new GameEvent(GameEvent.STAR)) 


    } 
    public function OnExitClick(myEvent:MouseEvent):void{ 
     //NativeApplication.nativeApplication.exit(); 

    } 


    protected function onSystemKey(e:KeyboardEvent):void 
    { 
     if(e.keyCode == Keyboard.BACK) 
     { 

      //NativeApplication.nativeApplication.exit(); 
     } 
     else if(e.keyCode == Keyboard.HOME) 
     { 
      //handle the button press here. 
     } 
     else if(e.keyCode == Keyboard.MENU) 
     { 

     } 
    } 

回答

2

它看起來像的原因是因爲你的onMain方法,您將從舞臺上移除,然後創建播放畫面的全新實例。所以你的聽衆會依附在舊的。這也會造成內存泄漏。

public function onMain(gameEvent:GameEvent):void{ 
     playScreen.removeChild(playScreen.menuScreen) 
     this.removeChild(playScreen) 
     //openScreen = new OpenScreen(); 
     openScreen.x = 0 
     addChild(openScreen) 
     playScreen = new PlayScreen(); //RIGHT HERE - this is creating a whole new play screen, your listeners are attached to the old one. 
} 

也許應該是這樣的:(取出播放屏幕的代碼在構造函數中,當你宣稱它不進行實例化)

//Create a function that kill your current play screen 
public function clearPlayScreen():void { 
    if(!playScreen) return; //don't do anything if there isn't a play screen 
    playScreen.removeChild(playScreen.menuScreen) 
    this.removeChild(playScreen); 

    //remove your listeners so the old play screen can be garbage collected - other they will all stay in memory causing a memory leak 
    playScreen.removeEventListener(GameEvent.NG, NewGame); 
    playScreen.menuScreen.removeEventListener(GameEvent.NG, NewGame, true); 
    playScreen.menuScreen.removeEventListener(GameEvent.MM, onMain); 

    playScreen = null; 
} 

public function NewGame(gameEvent:GameEvent):void{ 
    clearPlayScreen(); //kill the old play screen if it exists 

    playScreen = new PlayScreen(); 
    addChild(playScreen); 

    //add the listeners to the new play screen 
    playScreen.addEventListener(GameEvent.NG, NewGame); 
    playScreen.menuScreen.addEventListener(GameEvent.NG, NewGame, true, 0, true); 
    playScreen.menuScreen.addEventListener(GameEvent.MM, onMain); 

    playScreen.begin(); 
} 

public function onMain(gameEvent:GameEvent):void{ 
    clearPlayScreen(); 

    //openScreen = new OpenScreen(); 
    openScreen.x = 0; 
    addChild(openScreen); 
} 
+0

這是有道理的,這是一個問題,這樣做可以解決我的按鈕無法工作的問題。新的playScreen是我製作新遊戲的方式,因爲所有遊戲機制都包含在playScreen中。是否有更好的方法將該孩子重新設置爲被調用之前的方式? – Jimbo145

+1

可能是一種更高效的方式,但這取決於整個應用程序。清除和重新實例化沒有任何問題,只要確保內存中沒有任何內容保留以前的播放屏幕(如事件偵聽器) – BadFeelingAboutThis