I am relatively new to Action Script, and I am trying to make a game of Snake. Obviously I need to implement a global key listener, but I am having odd problems. I tried adding the listener to the application tag but it didn’t seem to have any effect (the movie was still able to compile). Whenever I call
this.stage.addEventListener(KeyboardEvent.KEY_DOWN, key, true);
my program crashes. Below is the content of my main.mxml file:
<?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>
Also, it seems I am getting this stack trace:
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]
I am at my wit’s end here, and I appreciate your time and efforts. Thanks!
You are getting a runtime error because you attach an event listener to the “stage” property, which is null at the time you try it. Instead of doing this on the “creationComplete” event, try to do this on the “applicationComplete” event. The stage object will be available then.