2010-12-19 66 views
0

添加一鍵收聽我是比較新的動作腳本,而我試圖讓蛇遊戲。顯然,我需要實現一個全局的關鍵監聽器,但我有一些奇怪的問題。我嘗試將偵聽器添加到應用程序標記,但它似乎沒有任何效果(電影仍然能夠編譯)。每當我打電話在動作腳本3

this.stage.addEventListener(KeyboardEvent.KEY_DOWN, key, true);

我的程序崩潰。下面是我的main.mxml文件的內容:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application 
xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute" 
width="800" 
height="600" 
frameRate="15" 
creationComplete="creationComplete();" 
enterFrame="enterFrame(event);" 
currentState="MainMenu"> 

<mx:states> 
    <mx:State 
    name="Game" 
    enterState="enterGame(event)" 
     exitState="exitGame(event)"> 
    </mx:State> 
    <mx:State 
    name="LevelEnd"> 
    <mx:AddChild relativeTo="{myCanvas}" position="lastChild"> 
    <mx:Button x="380" y="344" label="Continue" id="btnContinue" click="btnContinueClicked(event)" width="90" height="30"/> 
    </mx:AddChild> 
    <mx:AddChild relativeTo="{myCanvas}" position="lastChild"> 
    <mx:Label x="10" y="10" text="Congratulations, you finished the level."/> 
    </mx:AddChild> 
    </mx:State> 
    <mx:State name="MainMenu"> 
    <mx:AddChild relativeTo="{myCanvas}" position="lastChild"> 
    <mx:Button x="381" y="344" label="Start" id="btnStart" click="startGameClicked(event)" width="90" height="30"/> 
    </mx:AddChild> 
    <mx:AddChild relativeTo="{myCanvas}" position="lastChild"> 
    <mx:Image x="10" y="49" source="@Embed('../media/mainmenu.png')"/> 
    </mx:AddChild> 
    <mx:AddChild relativeTo="{myCanvas}" position="lastChild"> 
    <mx:Label x="10" y="10" text="Snake Pro" fontSize="20" fontWeight="bold"/> 
    </mx:AddChild> 
    </mx:State> 
</mx:states> 

<mx:Canvas x="0" y="0" width="100%" height="100%" id="myCanvas"/> 

<mx:Script> 
<![CDATA[ 

    protected var inGame:Boolean = false; 
    protected var currentLevel:int = 1; 
    import flash.events.KeyboardEvent; 

    public function creationComplete():void 
    { 
    LevelDefinitions.Instance.startup(); 
    addKeyEvent(); 
    //stage.focus = stage; 
    } 

    private function addKeyEvent():void 
    { 
    this.stage.addEventListener(KeyboardEvent.KEY_DOWN, key, true); 
    } 

    public function enterFrame(event:Event):void 
    { 
     if (inGame) 
     { 
     GameObjectManager.Instance.enterFrame(); 

     myCanvas.graphics.clear(); 
     myCanvas.graphics.beginBitmapFill(GameObjectManager.Instance.backBuffer, null, false, false); 
     myCanvas.graphics.drawRect(0, 0, this.width, this.height); 
     myCanvas.graphics.endFill(); 
     } 
    } 

     private function key(event:KeyboardEvent):void { 
      //t1.text = event.keyCode + "/" + event.charCode; 

    GameObjectManager.Instance.setDirection(0, 1); 
    currentState = "MainMenu"; 
    inGame = false; 
     } 

    protected function startGameClicked(event:Event):void 
    { 
    currentState = "Game" 
    }  

    protected function enterGame(event:Event):void 
    { 
    Mouse.hide(); 
    GameObjectManager.Instance.startup(); 
    Level.Instance.startup(currentLevel); 
    inGame = true; 
    } 

    protected function exitGame(event:Event):void 
    { 
    Mouse.show(); 
    Level.Instance.shutdown(); 
    GameObjectManager.Instance.shutdown(); 
    inGame = false; 
    } 

    protected function btnContinueClicked(event:Event):void 
    { 
    currentLevel = LevelDefinitions.Instance.getNextLevelID(currentLevel); 
    if (currentLevel == 0) 
    { 
    currentLevel = 1; 
    currentState = "MainMenu"; 
    } 
    else 
    { 
    currentState = "Game" 
    } 
    } 
]]> 
    </mx:Script> 

</mx:Application> 

而且,看來我得到這個堆棧跟蹤:

TypeError: Error #1009: Cannot access a property or method of a null object reference. 
    at main/addKeyEvent()[C:\Users\Me\Desktop\Flash\Snake\src\main.mxml:58] 
    at main/creationComplete()[C:\Users\Me\Desktop\Flash\Snake\src\main.mxml:52] 
    at main/___main_Application1_creationComplete()[C:\Users\Me\Desktop\Flash\Snake\src\main.mxml:10] 
    at flash.events::EventDispatcher/dispatchEventFunction() 
    at flash.events::EventDispatcher/dispatchEvent() 
    at mx.core::UIComponent/dispatchEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:12528] 
    at mx.core::UIComponent/set initialized()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:1627] 
    at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:759] 
    at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072] 

我在我束手無策這裏,我很欣賞你的時間和努力。謝謝!

回答

1

因爲你附加一個事件監聽器「階段」屬性,它是在你嘗試的時間空你得到一個運行時錯誤。而不是在「creationComplete」事件上這樣做,嘗試在「applicationComplete」事件上執行此操作。舞臺對象將可用。

+0

啊,我現在開始工作了。非常感謝! – kiryu1101 2010-12-19 15:48:45

0

這不是明顯,我認爲實現這個遊戲中你需要實現一個全球性的關鍵聽衆。從Flex應用程序的上下文中,將偵聽器添加到應用程序標記而不是階段是否更有意義?

什麼是完整的堆棧跟蹤,什麼都行你得到的錯誤?很可能你只需要添加一個條件,以便你不訪問尚未初始化的對象。

+0

我編輯我的職務,以顯示完整的堆棧跟蹤。我嘗試將偵聽器添加到應用程序標記,但它似乎沒有任何影響。 – kiryu1101 2010-12-19 03:57:01

1

您的應用程序可能不會添加到舞臺上呢,這就是爲什麼有一個在addKeyEvent被拋出的異常。話雖這麼說,你並不真正需要的事件監聽器添加到舞臺在這種情況下,您可以將其添加到應用程序,而不是像這樣:

<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" 
    width="800" 
    height="600" 
    frameRate="15" 
    creationComplete="creationComplete();" 
    enterFrame="enterFrame(event);" 
    currentState="MainMenu" 
    keyDown="key(event)"> 

由於是隱含的,你還需要刪除在你的creationComplete處理函數中調用addKeyEvent,否則你仍然會得到異常。

+0

添加keyDown屬性也沒有幫助。看來我錯過了一些東西,或者我的電影有邏輯錯誤。是否有觸發消息的方法(類似於JavaScript的alert()函數),我可以將它放入我的關鍵事件中? – kiryu1101 2010-12-19 04:47:47

+0

將keyDown事件添加到主應用程序標記時,您還需要刪除代碼以手動添加事件偵聽器。 – JeffryHouser 2010-12-19 12:25:55

+0

@ www.Flextras.com是正確的,您還需要在creationComplete處理程序中刪除對addKeyEvent的調用。我沒有提到它,但它是暗示的。我會更新答案以便更明確。 – 2010-12-19 14:08:20