So, in ActionScript 2.0, there existed such a thing as attachSound which would allow you to call on sounds in your library and iterate them in code much like you would call on movieclips in the library.
With ActionScript 3.0, there is no attachSound, so you need to do a little workaround. It took me a while to find this, but here you go:
import flash.utils.getDefinitionByName;
import flash.media.Sound;
var mySound:Sound;
var librarySound:Class = getDefinitionByName ( "nameOfYourSoundasLinkedFromTheLibrary" ) as Class;
mySound = new librarySound();
Basically, anything that you’re referring to as an Object in ActionScript 3.0 seems to require having a class file. So when you go to your library and export your sound objects for ActionScript, a class file is published for each one, and you need to call on these as a class in your code in order to use them like you would an external .mp3 or other audio file.
Now, for the fun part — remember what a pain in the ass it was to trigger some kind of event when an audio file would stop playing in Flash circa ActionScript 2.0? Throw the following code in to the above:
import flash.media.SoundLoaderContext;
import flash.media.SoundChannel;
var myChannel:SoundChannel;
myChannel = mySound.play();
myChannel.addEventListener( Event.SOUND_COMPLETE, AudioDoneAction );
function AudioDoneAction( event:Event ):void
{
// Do something when the audio is done
}
So basically, the Sound class in ActionScript 3.0 allows you to load sounds and play them, but if you want to manipulate them or use them to evaluate other stuff, you want to include the Sound object as a reference in a SoundChannel object.
This seems pretty overcomplicated for my simple example here, but think about it this way. What if you had five different external audio files you wanted to load as a playlist for just one slide in an E-Learning piece, and you wanted to trigger different images and text with each audio file. You can code yourself a playlist and trigger changes upon completion of an audio file — and even track where you are in the playlist so that you could have different actions upon completion of the first and/or the last (or really at any defined place in the order of) audio in the playlist.
I couldn’t figure out the embedded audio as class thing on my own. It took a while of experimenting and searching until I found the solution here and here.
I promised actual Flash stuff on this blog, and now I start to make good on that promise. And no, this is not as clever as Philip Hutchinson’s SCORM Class(es), but give me a break! ActionScript 3 is kinda hard when you don’t touch Flash everyday.
Based only on this one experience, the good news for you if you want to upgrade your existing code to ActionScript 3.0: much of the foundation of the original ActionScript 2.0 code stayed in-tact. The bad news: figuring out how to convert the way you reference things in ActionScript 3.0 is a bit awkward when you’re used to working with AS2.0 and it took me a lot longer than I expected.
In some ways, upgrading my Asteroids code from ActionScript 1.0 might be easier than my experiments trying to do it in ActionScript 2.0, but… I need to budget a lot of time to accomplish that feat, I think.
Feel free to give this a try and if you have any questions or changes — if you have a way to improve or expand it, please share because I am always looking to improve (and I’m trying to get better about demonstrating that).
This code can actually go on the main timeline (I know, not cool for you OOP types, but I wanted to make it easy for people to just copy, paste and play). It assumes that you have a font (Verdana, in this case) in your library called “Verdana” that is exported to ActionScript.
I’ve made the attempt to have the font size increase or decrease relative to the height of the button.
import flash.geom.*;
import flash.display.*;
// FEEL FREE TO CHANGE THESE VALUES, AS THE REST OF THE CODE WILL ADAPT
var radius:int = 24; // The corners of your button
var btnW:int = 360; // Button Width
var btnH:int = 120; // Button Height
var colors:Array = [0xff0090, 0xff0000]; // The main gradient of your button
var strID:String = "Shiny Button"; // Button Label
var intX:int = 0; // X-Position of your button's upper-left corner
var intY:int = 0; // Y-Position of your button's upper-left corner
// PLAY WITH THESE AT YOUR RISK
var fillType:String = GradientType.LINEAR;
var alphas:Array = [100, 100];
var ratios:Array = [0, 245];
// TRY TO LEAVE EVERYTHING ELSE ALONE...
var matr:Matrix = new Matrix();
matr.createGradientBox( btnW, btnH, 90/180*Math.PI, 0, 0 );
var spreadMethod:String = SpreadMethod.PAD;
var myButton:MovieClip = new MovieClip();
this.addChild( myButton );
myButton.x = intX;
myButton.y = intY;
// BUTTON BACKGROUND
var buttonBkg:Sprite = new Sprite();
buttonBkg.graphics.lineStyle(0, 0xE88A41, 100, true, "none", "square", "round");
buttonBkg.graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod );
buttonBkg.graphics.moveTo(radius, 0);
buttonBkg.graphics.lineTo((btnW-radius), 0);
buttonBkg.graphics.curveTo(btnW, 0, btnW, radius);
buttonBkg.graphics.lineTo(btnW, (btnH-radius));
buttonBkg.graphics.curveTo(btnW, btnH, (btnW-radius), btnH);
buttonBkg.graphics.lineTo(radius, btnH);
buttonBkg.graphics.curveTo(0, btnH, 0, (btnH-radius));
buttonBkg.graphics.lineTo(0, radius);
buttonBkg.graphics.curveTo(0, 0, radius, 0);
buttonBkg.graphics.endFill();
// ADD THE BUTTON BACKGROUND TO THE FANCY BUTTON ONLY AFTER IT'S READY
myButton.addChild( buttonBkg );
// THE SHINY GLASSY EFFECT
var shineRadius:Number = radius * 2 / 3;
var shineW:Number = btnW - ( 0.0333 * btnW );
var shineH:Number = btnH / 2 - ( 0.0667 * btnH );
var shineFillType:String = GradientType.LINEAR;
var shineColors:Array = [0xFFFFFF, 0xFFFFFF];
var shineAlphas:Array = [70, 0];
var shineRatios:Array = [0, 255];
var shineMatr:Matrix = new Matrix();
shineMatr.createGradientBox( shineW, shineH, 90/180*Math.PI, 0, 0 );
var shine:Sprite = new Sprite();
shine.x = ( 0.0333 * btnW ) / 2;
shine.y = ( 0.0667 * btnH ) / 2;
shine.graphics.lineStyle(0, 0xFFFFFF, 0);
shine.graphics.beginGradientFill(shineFillType, shineColors, shineAlphas, shineRatios, shineMatr, spreadMethod );
shine.graphics.moveTo(shineRadius, 0);
shine.graphics.lineTo((shineW-shineRadius), 0);
shine.graphics.curveTo(shineW, 0, shineW, shineRadius);
shine.graphics.lineTo(shineW, (shineH-shineRadius));
shine.graphics.curveTo(shineW, shineH, (shineW-shineRadius), shineH);
shine.graphics.lineTo(shineRadius, shineH);
shine.graphics.curveTo(0, shineH, 0, (shineH-shineRadius));
shine.graphics.lineTo(0, shineRadius);
shine.graphics.curveTo(0, 0, shineRadius, 0);
shine.graphics.endFill();
// ADD THE SHINY PART TO THE BUTTON ONLY AFTER IT'S BEEN GENERATED
myButton.addChild( shine );
// TEXT FORMAT FOR THE BUTTON LABEL
var myFormat:TextFormat = new TextFormat();
myFormat.align = "left";
myFormat.font = "Verdana";
myFormat.size = 12 * Math.round( 0.0125 * btnH );
myFormat.bold = true;
myFormat.color = 0xFFFFFF;
// THE BUTTON LABEL
var labelText:TextField = new TextField();
labelText.x = ( 0.0333 * btnW ) / 2;
labelText.y = ( 0.333 * btnH );
labelText.text = strID;
labelText.embedFonts = true;
labelText.selectable = false;
labelText.type = TextFieldType.DYNAMIC;
labelText.autoSize = TextFieldAutoSize.LEFT;
labelText.antiAliasType = "advanced";
labelText.setTextFormat( myFormat );
// ADD THE TEXTFIELD ONLY AFTER IT'S COMPLETE
myButton.addChild ( labelText );
With my 3G iPod nano, I’ve run the course on getting my learn on as far as adjusting my fantasy football team or catching up on political satire. This weekend I was getting jiggy with ActionScript 3 and actively sought out what podcasts might be available, video or otherwise, on the subject.
I didn’t find much. However, I found at least one use of podcasting that are extending the official knowledge out there. I’ve been reading the ActionScript 3.0 Game Programming University by Gary Rosenzweig off my Safari account to get a little more hands-on with the code. Turns out, Gary also has a podcast that extends the lessons in the book, complete with screen grabs (done on the Mac, just to needle it in for some of you) on how to further modify or extend the code examples detailed in some of the lessons. That’s pretty nifty from both a marketing and an educational perspective.
I’d love to find out more about podcasts centered around Flash, Actionscript 3 or scripting in general (for all my experimentations and tutorials, Ruby on Rails still isn’t taking for me — and neither is Flex).
Whew, it’s been a long time since I actually touched code, but after three months of writing up nothing but process and standards documents, an email (and guestbook entry) really got me motivated to do something I’ve talked for a while now.
What I’ve assembled here is a full-on SCORM 1.2-conformant content package of how Flash 8 can use ExternalInterface to work with the good ol’ ADL APIWrapper.js to get information in and out of Flash. I even incorporated bookmarking to give you an idea of just how easy it is.
After toiling away on the job stuck in Flash 7 last year, and clunking around the noble (but limiting) Flash-JavaScript Integration Kit from osFlash, it was fun to tinker around in just a little bit of time and get the underpinnings down for talking to an LMS all out of Flash.
It even runs in Saba :O.
Anyway, the content package is here. It includes the .fla. Feel free to comment away or ask questions.
As I’ve been checking out ADL’s forums today, I revisited the thread where the questions about how to work with Flash Player 8’s security model originally came up.
Another user on the forum posted this link to Macromedia’s DevNet which details how to work around the various sandbox security settings in the new Flash player.
It’s been confirmed that I will be presenting at this year’s MAX 2005 conference, hosted by Macromedia. Here’s the info I can confirm right now (I’m very psyched).
Title: Robust SCORM-Compliant eLearning Content with Flash and Captivate
This session will include tricks to synchronizing communication with
JavaScript from Flash, building familiarity with the SCORM Run-Time
data model and testing content with the ADL SCORM 2004 Test Suite. We
will also address best practices when creating interactions in a
Captivate movie (and what they mean with an LMS), and debugging help.
More news coming as to what the plans are, but I promise you that my partner Alan and I are going to make developing SCORM-conformant content with plain ol’ Flash WAY easier than it’s ever been — you might even think it to be (dare I say it)… easy.
I was away learning about Knowledge Management this week, which will occupy several blog entries as what I learned from this conference experience relates directly to the purpose of this site.
But, I also wanted to let you know how easy it is to use classes that other people author.
As you can see, I have collision detection working. And I barely wrote any code. In fact the class that runs this is directly from Grant Skinner, who released his ProxmityManager class on his site back in February. After reading Branden Hall’s blog using the same methodology as far as dividing the screen into a grid, and then, when the ship is in a particular block, it checks the neighboring blocks for asteroids.
So I didn’t expand on the interaction between the ship and the asteroids. Instead, I tooled around all weekend trying to create randomly shaped polygons to use for the asteroids. This is something I wanted to do in the original build and never took the time to concentrate on the problem.
I read several articles online. Looked at academic research on a Random Polygon Generator. The algorithms were mind boggling. I e-mailed some very smart ActionScript programmers for some help. None came (at least by the time of this writing).
Then it occurred to me… can’t I just rotate similar-sized squares and triangles appearing randomly to produce a randomly shaped polygon? Bet your ass I could
It would figure that success breeds more success, and now I have a ship that flys about the screen using the arrow keys, again controlled via a Ship class. Try it for yourself right here!
Flash For Learning is written by Aaron Silvers, Learning Strategist for a multinational corporation. He writes about Flash and Flash-related topics for E-Learning, as well as other musings on organizational learning, within the context of Knowledge Management. Aaron is also a husband, dad, cyclist, musician and nerd.