Flash和Flex SDK / AS3-如何保持键盘焦点?

4
我正在使用Flex/AS3编写Flash应用程序,但似乎无法分配键盘焦点。开发早期我就意识到这个问题,并添加了一个带有“现在播放”按钮的启动屏幕,以吸引用户点击。然而,用户必须再次单击应用程序才能使键盘起作用!
更糟糕的是,我有一个游戏内快捷键,可以返回主菜单。如果您返回主菜单,然后再次单击“现在播放”按钮,则SWF会再次失去焦点!
我可能弄错了子对象或意外销毁了捕获键盘焦点的对象,但我不太确定它是如何工作的。你能帮我指明正确的方向吗?
我的应用程序是一个单一的.SWF文件,我直接在浏览器中运行它(尽管最终我会通过网页调用它)。这里是相关的文件: http://www.space-squid.com/game/Main.swf 当您单击“Normal”时,必须再次单击才能实际抓取键盘焦点。:( 随时提问!
编辑:这是我正在使用的一些代码。

我主要类中执行的一些最初的代码:

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

我也尝试过这种情况,以防我应该在我的根对象上设置钩子:

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

如果空精灵引起了问题:
background_image = new BackgroundImage();
background_image.x = etc etc alignment data;
addChild(background_image);
background_image.stage.addEventListener(keyboard hooks...)

在所有这些例子中,只要我第二次点击,我的键盘钩子就能正常工作,但从来没有第一次。:( 第二次编辑: 我已经缩小了问题范围。也许有人可以帮我解决这个问题,这可能是一个结构问题:
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);
}

正如您所看到的,我创建了“现在播放”按钮 - 然后似乎它成为了焦点对象。由于背景正在寻找焦点,因此我的键盘事件无法被捕获。不确定这是否有意义,希望有人能够帮助我解决这个问题!
如果我注释掉那一行(removeChild(PlayNowButton)),游戏就可以完美地运行并保持键盘焦点 - 缺点是屏幕上会永远有一个“播放”按钮。
老实说,我甚至不确定游戏本身是否在第一次单击时接收到焦点,但我不知道如何测试。

你的启动画面是如何工作的?它是同一个swf文件的一部分吗?如果作为独立的swf文件运行,应用程序会有不同的行为吗? - quoo
它是同一SWF的一部分 - 我不使用网页查看文件,我只是直接在浏览器中加载SWF。 - Andy Moore
2个回答

13

你要寻找的代码是:

gameWorldObject.stage.focus = this;

由于Flash已经获得了焦点,因此您的键盘事件处理程序在Flash应用程序本身中没有焦点。您可以使用上面的代码切换应用程序中当前的焦点位置。

或者,如果不想销毁PlayNow按钮,将其设为不可见也可以达到相同的效果。然后在需要时再次将其设为可见即可。如果它是MovieClip或Sprite对象,则非常容易:

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

(以这种方式给自己写东西很难)


这个解决方案对我有效。我仍然不知道为什么删除子剪辑会导致这个问题。 - 1owk3y

2

我猜这是一个浏览器项目?

这是我的做法:

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()");
        }
        // ...
     }
     //...
}

任何问题,请确保您的嵌入/对象标记具有ID和名称属性!


更新了问题;这会让 SWF 获得焦点,但点击“立即播放”会再次取消焦点。 :( - Andy Moore
假设在您的HTML/XML文档中只有一个SWF,一旦它获得焦点,除非文档中其他元素或浏览器插件在干扰,否则它不应该失去焦点。您是否有实时演示或页面源代码的pastie?(注:如果它不在文档中,您将遇到无休止的浏览器问题) - Billy Back Bedroom
我这里有一个例子:http://www.space-squid.com/game/Main.swf 当你点击“Normal”时,你必须再次点击才能真正抓住键盘焦点。 - Andy Moore
@18:32 4月27日 - 我看了你的例子,它是有效的。这是因为你已经修复了它吗? - Billy Back Bedroom
是的,我已经解决了,并在下面为自己发布了答案。不过我得等一会儿才能标记它 :) - Andy Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接