Thursday, December 4, 2008

Dynamically loading embedded images in AS3

Huge kudos for a post found on UltraShock that saved me today when I was on a crazy deadline to finish something:

I had recently completed a project that was built as a flash projector file. Originally the movie used external .jpg's that loaded at runtime, but to make it safer to distribute it was decided that all of the jpgs had to be embedded into the swf and loaded from there.

The actionscript stored all of the image names in an array and called them in sequence to load into a movieclip. To do this I just used a Loader() object. However when moving the assets into the swf I couldn't (quickly) find a simple way to load them dynamically anymore.

The first step was to turn each image into its own class with the filename as the class name -- so IMG_45.jpg was turned into a class (using the linkage panel) called IMG_45, etc. So far so good. But then we got stumped on how to load it dynamically. While I could have made them all movieclips, put them all on the timeline and called: this['IMG_45'] -- but that would have required that all 60 high res images be placed on the stage and probably killed performance.

In the end I had about 15 minutes to find a way to load the specific class when all I had was a the name of it -- as a string.

Anyway, some Googling found this brilliant function that solved it in 5 minutes instead:

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.getDefinitionByName;

var bitmapData:BitmapData = getBitmapData(myImg);
var bitmap:Bitmap = new Bitmap( bitmapData ); this.addChild(bitmap);

function getBitmapData( className:String ):BitmapData{
var obj:BitmapData;
var cls:Class = getClass( className );

try{
obj = new cls( 0, 0 );
}catch(err:Error){}

return obj;
}

function getClass( className:String ):Class{
return getDefinitionByName(className) as Class;
}

Awesome -- truly!!

stopAllSounds() in as3

FYI - The old stopAllSounds() method in Actionscript 2 has been replaced with the static method SoundMixer.stopAll()

You implement it this way:

import flash.media.SoundMixer;

SoundMixer.stopAll();

Tuesday, December 2, 2008

Facebook: can't next fb:name inside of a meta tag of an fb:share-button

This won't work:

<fb:share-button class="meta">

<meta name="medium" content="blog"/>

<meta name="title" content="<fb:name uid=<?php echo $userid ?> useyou=false /> found this great video"/>

<meta name="video_type" content="application/x-shockwave-flash"/>

<meta name="video_height" content="345"/>

<meta name="video_width" content="473"/>

<meta name="description" content="Cleaning the coastline"/>

<link rel="image_src" href="http://mysite.com/myimage.jpg"/>

<link rel="video_src" href="http://mysite.com/myimage.flv"/>

<link rel="target_url" href="http://mysite.com"/>

</fb:share-button>


Now you are probably wondering why I wouldn't just set the name var in php and print that instead but this was being used as the return call from ajax and I wanted to try and use the fb:name tag just like any other fb tag. But it doesn't work. So it appears that "some" fb tags can be nested but not this one (or just not in this way).

As a workaround I sent the name along with the other params in the ajax call and just built the whole string on the server instead:


<?php

$username = $_GET['username'];

$itemId = $_GET['itemId'];

$itemDescription = $_GET['itemDescription'];

$itemURL = $_GET['itemURL'];

$itemImage = $_GET['itemImage'];

$itemType = $_GET['itemType'];


if($itemType=='video'){



echo '<fb:share-button class="meta"> <meta name="medium" content="blog"/> <meta name="title" content="' . $username . ' found this great video on Baha\'i Explorer"/><meta name="video_type" content="application/x-shockwave-flash"/><meta name="video_height" content="345"/> <meta name="video_width" content="473"/> <meta name="description" content="'. $itemTitle . '"/> <link rel="image_src" href="http://i3.ytimg.com/vi/'. $itemId . '/default.jpg"/> <link rel="video_src" href="http://www.youtube.com/v/' . $itemId . '&hl=en&fs=1"/> <link rel="target_url" href="' . $itemURL .'"/> </fb:share-button>';

}

 

?>

Facebook share pod causes flash to become invisible

Another problem with Facebook and Flash playing together. Using the fb:share-button: when the user clicks it the share pod appears in IE but it also makes the flash on the page disappear. This only happens in IE. I've tried setting the fb:swf wmode param to transparent but it doesn't help. Very frustrating...

update: I thought of a really cheap (but workable) hack. I've made a screenshot of the flash app and then covered it with a 80% black tint and made a .jpg. This is used as the background of the div that surrounds the flash movie. This way, when a user clicks on the share and the flash disappears the disabled grayed out image shows instead -- making it "look" like everything is fine. Of course the state is different (different text is showing for instance) but the user is focused on the share pod anyway.

I'm not thrilled with it but it will work for the time being until I can figure out how to have flash make calls directly to the server. Perhaps I should be skipping to Facebook Connect??