In an AS3 game (using Flex 4.10.0) I would like to allow players to chat, even when they are in fullscreen mode.
So I am using the following ActionScript code (the _fullBox
checkbox triggers fullscreen mode in my web application):
public function init():void {
if (stage.allowsFullScreenInteractive)
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen, false, 0, true);
}
private function toggleFullScreen(event:MouseEvent):void {
stage.displayState =
stage.displayState == StageDisplayState.NORMAL ?
StageDisplayState.FULL_SCREEN_INTERACTIVE :
StageDisplayState.NORMAL;
}
private function handleFullScreen(event:FullScreenEvent):void {
_fullBox.selected = event.fullScreen;
}
<s:CheckBox id="_fullBox" click="toggleFullScreen(event)" label="Full Screen" />
This works in the sense that the fullscreen mode is entered successfully and users can use the keyboard to chat too.
Unfortunately, the click at the "Allow" button in the dialog (displaying "Allow full screen with keyboard controls?") is being passed down to the web application.
And in my case it resuls in the click at a playing table in the lobby as you can see in the screenshot and thus (unwanted) joining a game:
This (bug?) has been seen with Windows 7 / 64 bit and Flash Player 11,8,800,115.
Can anybody please share a good workaround for this?
I was thinking of adding a transparent Sprite
or UIComponent
above my web application, but the question is when (i.e. in which methods) to display/hide it?
UPDATE:
Calling event.stopPropagation()
from handleFullScreen()
doesn't help anything.
UPDATE 2:
I've submitted Bug #3623333 at Adobe.
UPDATE 3: A note to myself - stage.allowsFullScreenInteractive
is useless, because only set when allready in fullscreen mode.
As you mentioned, you need to create transparent layer to avoid undesired click events. you can hide this layer when screen returned to normal state or user accepted fullscreen state (FULL_SCREEN_INTERACTIVE_ACCEPTED
event will fired).
Demo (flashplayer 11.3 required)
var transparentLayer:Sprite=new Sprite();
var timer:Timer = new Timer(50, 1);
init();
function init():void {
transparentLayer.graphics.beginFill(0,0.1);
transparentLayer.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
transparentLayer.graphics.endFill();
transparentLayer.visible=false;
addChild(transparentLayer);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,handleTimerComplete);
stage.addEventListener(FullScreenEvent.FULL_SCREEN_INTERACTIVE_ACCEPTED,handleFSIA);
_fullBox.addEventListener(MouseEvent.CLICK,toggleFullScreen);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);
}
function toggleFullScreen(e:MouseEvent):void {
if(stage.displayState == StageDisplayState.NORMAL){
stage.displayState=StageDisplayState.FULL_SCREEN_INTERACTIVE;
transparentLayer.visible=ExternalInterface.available;
}else
stage.displayState=StageDisplayState.NORMAL;
}
function handleFullScreen(e:FullScreenEvent):void {
_fullBox.selected = e.fullScreen;
if(stage.displayState == StageDisplayState.NORMAL)
transparentLayer.visible=false;
}
function handleFSIA(e:FullScreenEvent):void{
timer.reset();
timer.start();
}
function handleTimerComplete(e:TimerEvent):void{
transparentLayer.visible=false;
}
Found one workaround.
Allow and Cancel buttons are not the parts of the application, so when you hover one of those buttons you receive rollOut event for application.
<s:Application
rollOut="application_rollOutHandler(event)"
rollOver="application_rollOverHandler(event)">
Inside event handler you can disable mouse events for child objects. Don't disable for application as you won't get rollOver event after that.
private function application_rollOutHandler(event:MouseEvent):void
{
this.mouseChildren = false;
}
private function application_rollOverHandler(event:MouseEvent):void
{
this.mouseChildren = true;
}