2010-12-19 71 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