Tutorial :Flash & Flex SDK/AS3 - How to keep keyboard focus?


I'm writing a flash application in Flex/AS3, and I can't seem to assign keyboard focus to it. I was mindful of this problem early on in development and added a splash screen with a "play now" button, to entice the user to click. However, the user must then click a second time on the application for the keyboard to work!

To make matters worse, I have an in-game shortcut that returns you to the main menu. If you return to the main menu then click the "play now" button, the SWF loses focus again!

I'm probably messing up children objects or accidentally destroying an object that captured the keyboard focus, but I'm not quite sure how it works. Can you help point me in the right direction?

My application is a single .SWF file, and I am running it directly in my browser (not calling it via a webpage, though I will eventually). Here is the file in question:

http://www.space-squid.com/game/Main.swf When you click on "Normal" you have to click a second time to actually grab the keyboard focus. :( Feel free to ask questions!

Edit: Here's some code I'm using.

Some of the first code that executes in my primary class:

empty_sprite = new Sprite();  addChild(empty_sprite);  empty_sprite.stage.addEventListener(keyboard hooks...);  

I've also tried this just in case I should have set the hooks on my root object:

this.stage.addEventListener(keyboard hooks...);  

In case the otherwise empty sprite was causing issues:

background_image = new BackgroundImage();  background_image.x = etc etc alignment data;  addChild(background_image);  background_image.stage.addEventListener(keyboard hooks...)  

In all of these examples my keyboard hooks work fine, as long as I click the second time.. but never the first. :(

SECOND EDIT: Well I've narrowed the problem down. Perhaps someone can help me straighten this out, it's probably a structure problem:

public function Main {      Some stuff...      empty_sprite = new Sprite(); // Create a new stage sprite      addChild(empty_sprite);      empty_sprite.stage.addEventListener(keyboard hooks...);                addChild(BackgroundImage); // I lay down my background image which is persistant        addChild(PlayNowButton); // I display my PlayNow button to the screen        More stuff...  }    public function StartGame() {      removeChild(PlayNowButton); // This is the point of failure; this removes focus.      removeChild(otherMenuOptions);      ...      addChild(gameComponents);  }  

As you can see, I create the play now button - and it appears that becomes the object of focus. My keyboard events aren't being trapped as it's the background that is looking for the focus. Not sure if that makes sense, hopefully someone can straighten me out with this!

If I comment out that single line (removeChild(PlayNowButton)) the game works perfectly fine and retains keyboard focus - with the downside of having a "playnow" button overlaid on the screen forever.

To be honest I'm not even sure if the game itself ever receives focus on the first click but I'm not sure how to test for that.


The code you are looking for is:

gameWorldObject.stage.focus = this;  

Since Flash has obtained focus, your keyboard event handler is simply not focused within the flash application itself. You can switch where the current focus is within the application using the above code.

Alternatively, instead of destroying the PlayNow button, making it invisible will do the trick. Then make it visible again later when you need it to. Very easy if it's a MovieClip or a Sprite object:

PlayNowButton.visible = false; // or true obviously, as the case may be  

(It's hard writing to myself this way)


I'm assuming this is a browser project?

Here is how I do it:

package com.whatever.utilities {        import flash.external.ExternalInterface;         public class Browsers {            public static function FocusThisSwf():void {              if(!ExternalInterface.available)                  return;              ExternalInterface.call("eval", "document.getElementById('" +                  ExternalInterface.objectID + "').focus()");          }          // ...       }       //...  }  

Any hiccups, make sure your embed/object markup has an ID and Name attribute!

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »