我对动作脚本相对较新,我正在尝试制作一个Snake游戏。显然我需要实现一个全局键监听器,但我遇到了奇怪的问题。我尝试将监听器添加到应用程序标签但它似乎没有任何效果(电影仍然能够编译)。每当我打电话
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]
我在这里结束了我的智慧,我感谢你的时间和努力。谢谢!
答案 0 :(得分: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的调用,否则你仍然会得到异常。
答案 1 :(得分:1)
您收到运行时错误,因为您将事件侦听器附加到“stage”属性,该属性在您尝试时为null。而不是在“creationComplete”事件上执行此操作,尝试在“applicationComplete”事件上执行此操作。然后阶段对象将可用。
答案 2 :(得分:0)
对我来说,实现这个游戏并不是很明显,你需要实现一个全局的关键监听器。从Flex应用程序的上下文中,将监听器添加到应用程序标签而不是阶段是不是更有意义?
您的完整堆栈跟踪是什么,您收到错误的是哪一行?很可能你只需要添加一个条件,这样你就不会访问尚未初始化的对象。