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

10,873

Solution 1

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)

Solution 2

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!

Share:
10,873
Andy Moore
Author by

Andy Moore

Updated on June 19, 2022

Comments

  • Andy Moore
    Andy Moore almost 2 years

    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.

  • Andy Moore
    Andy Moore about 15 years
    Updated the question; this would work to give the SWF focus but clicking "play now" removes it again. :(
  • Alex
    Alex about 15 years
    Assuming there is only one SWF in your HTML/XML document, once it has focus it shouldn't ever lose it - unless something else in the document or a browser add-on is interfering. Do you have a live demonstration, or a pastie of the page source? (ed: if it isn't in a document, you'll have no end of browser troubles)
  • Andy Moore
    Andy Moore about 15 years
    I have an example up here: space-squid.com/game/Main.swf When you click on "Normal" you have to click a second time to actually grab the keyboard focus.
  • Alex
    Alex about 15 years
    @18:32 April 27 - I looked at your example, and it was working. Is this because you have since fixed it?
  • Andy Moore
    Andy Moore about 15 years
    Yep fixed it and posted an answer below for myself. I've got to wait before I can mark it though :)
  • 1owk3y
    1owk3y over 7 years
    This solution worked for me. I still have no idea why removing a child clip causes this issue.