Flash Overlay Quick Start
From Blue Mars Developer Guidebook
|
|
Contents |
Overview
This article provides a quick introduction to the FlashOverlay feature, building an example from scratch.
Before deciding to use FlashOverlay, consider whether the HUD is more appropriate. FlashOverlay is a window on top of the Blue Mars client that supports full Flash features including standard components and web access, so it would be suitable, for example, for a Help window with video tutorials or an elaborate editor or control panel. For Flash movies that are intended as on-screen elements, where you want control over input and better transparency (and non-blocking of mouse clicks on surrounding transparent areas), the HUD is more suitable. See the Golf game for a comprehensive example.
Flash
Getting Started
We'll start off by creating a blank Flash project (in this case, a Flash Actionscript 3 document in Adobe Flash CS3), and then Publish it.
The minimal Lua code we'll need to display the swf file:
function OverlayTest::ShowFlash()
local handler = {}
local flash
flash = FlashOverlay.New(handler,"http://mysite.com/emptyflash.swf")
end
For example, we can test it by triggering it from ARAvatarTrigger (note that FlashOverlay only works in the Blue Mars client, not the Editor)
However, if we run this code, we'll get this error.
The problem is that FlashOverlay timed out waiting for the onInit handler to be called from the Flash file (this is a default onInit handler, since we haven't specified one). So we'll go back to Flash and add an Actionscript call to onInit in frame 1, via ExternalInterface.
Note that the import line appears to be unnecessary in Actionscript 3, but it is require in Actionscript 2 (and will silently fail without it).
Now if we run the Lua code again, we'll see something.
Calling Lua from Flash Overlay
At this point,we'd like to see something more interesting, so we'll go back to Flash and add a Button component.
And we might as well make this button do something, let's go to our Actionscript and add a button click handler that makes another call to one of our Lua callbacks, this time onEnd.
import flash.external.ExternalInterface;
ExternalInterface.call("onInit");
closeButton.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
ExternalInterface.call("onEnd");
}
Before we Publish the swf file, let's make our button bigger and resize the document so we don't have a lot of excess background (that's a case-by-case decision - sometimes you may want to cover the whole game screen, sometimes you just want something smaller on screen that doesn't block mouse clicks elsewhere).
Now if we run our Lua code again, we'll see the button and clicking on it will make it disappear.
However, the default size and position are probably never going to be what you want (and notice the aspect ratio isn't right either, so it's vertically stretched), so let's add our own onInit handler to our handler table, specifying the actual size of the Flash display (210x110) and positioning at 100,200 from the top left corner of the screen.
function OverlayTest::ShowFlash()
local handler = {}
local flash
function handler.onInit(res)
flash:SetGeometry(100,200,210,110)
flash:Show()
end
flash = FlashOverlay.New(handler,"http://mysite.com/buttonflash.swf")
end
Now, this is more like what we expected.
You may notice that with the Flash overlay displayed, we still can interact with the rest of the screen normally, e.g. click on the standard Blue Mars buttons and move the avatar around. If we want to disable normal Blue Mars controls while our overlay is up, say if we have selection or confirmation popup that requires immediate attention, then we can call ARVirtualWorld.Instance:HideHUD() in our onInit handler. We'll also want to call ShowHUD when the overlay is dismissed, so we'll specify our own onEnd callback with that call. Since we're not relying on the default onEnd callback to hide the overlay, we'll also call the overlay Hide function explicitly.
function OverlayTest::ShowFlash()
local handler = {}
local flash
function handler.onInit(res)
ARVirtualWorld.Instance:HideHUD()
flash:SetGeometry(100,200,210,110)
flash:SetTransparency(1)
flash:Show()
end
function handler.onEnd(res)
flash:Hide()
ARVirtualWorld.Instance:ShowHUD()
end
flash = FlashOverlay.New(handler,"http://mysite.com/buttonflash.swf")
end
Now when our button overlay is displayed, the standard Blue Mars on the top left are gone, and avatar navigation is disabled.
Calling Actionscript from Lua
Besides calling Lua functions from Actionscript, we can call Actionscript functions from Lua. To be called from outside the Flash movie, Actionscript functions need to be registered with ExternalInterface.addCallback (note that the Actionscript 2 version of ExternalInterface.addCallback requires an additional parameter)
For example, let's say we imported a sound and define a PlaySound function. We can call it from Lua by registering it as a callback.
import flash.external.ExternalInterface;
ExternalInterface.call("onInit");
closeButton.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
ExternalInterface.call("onEnd");
}
ExternalInterface.addCallback("PlayMusic",PlayMusic);
function PlayMusic():void {
var mySound:MySound = new MySound();
mySound.play();
}
From Lua, we can now call our Actionscript PlayMusic function.
function OverlayTest::ShowFlash()
local handler = {}
local flash
function handler.onInit(res)
ARVirtualWorld.Instance:HideHUD()
flash:SetGeometry(100,200,210,110)
flash:SetTransparency(1)
flash:Show()
flash:CallMethod("PlayMusic")
end
function handler.onEnd(res)
flash:Hide()
ARVirtualWorld.Instance:ShowHUD()
end
flash = FlashOverlay.New(handler,"http://mysite.com/buttonflash.swf")
end
We aren't restricted to overriding default handler functions. Let's say in our click handler we wanted to call a Lua function to display a debug message.
function clickHandler(event:MouseEvent):void {
ExternalInterface.call("DebugMessage","Welcome to Blue Mars!");
}
<pre>
We could define the corresponding handler function in Lua:
<pre>
function handler.DebugMessage(res)
ARDebugMessage("Message from Flash Overlay: "..asobject2lua(res[2][1]))
end
Any additional arguments supplied to ExternalInterface are packaged in a table - specifically, the second element of the table is an array of Actionscript objects corresponding to the arguments. So they have to be converted to Lua objects using asobject2lua.
Flex
We can also use FlashOverlay with Flash files created using Flex. For example, the simple button example we created in Adobe Flash CS3 could also be constructed with this Flex script.
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="ExternalInterface.call('onInit')">
<mx:Button label="Close" click="ExternalInterface.call('onEnd')"/>
</mx:Application>
The High Score Flex Example is more elaborate.




