Добавление ключевого слушателя в Action Script 3 - PullRequest
0 голосов
/ 19 декабря 2010

Я относительно новичок в Action Script и пытаюсь создать игру в 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]

Я нахожусь в конце моего остроумия здесь, и я ценю ваше время и усилия. Спасибо!

Ответы [ 3 ]

1 голос
/ 19 декабря 2010

Возможно, ваше приложение еще не добавлено на сцену, поэтому в 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)">

Как подразумевается, вам также нужноудалить вызов addKeyEvent в вашем обработчике creationComplete, иначе вы все равно получите исключение.

1 голос
/ 19 декабря 2010

Вы получаете ошибку времени выполнения, потому что вы присоединяете прослушиватель событий к свойству «stage», которое является нулевым во время его попытки.Вместо того чтобы делать это для события «creationComplete», попробуйте сделать это для события «applicationComplete».Объект сцены будет доступен тогда.

0 голосов
/ 19 декабря 2010

Для меня не очевидно, что для реализации этой игры вам нужно реализовать слушатель глобального ключа.Разве из контекста приложения Flex не имеет ли смысла добавлять слушателя в тег приложения, а не в сцену?

Какова ваша полная трассировка стека, по какой строке вы получаете ошибку?Скорее всего, вам просто нужно добавить условие, чтобы вы не обращались к объекту, который еще не был инициализирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...