Adding any old library object to a display list

Ok, so you know this used to be pretty straightforward in AS2:

var mc:MovieClip = attachMovie(linkageid, newname, depth);

By in AS3, all of you linked library objects are now classes, so you need to do this with the class name:

var mc:Thingy = new Thingy();

What if you want to attach any random movieclip at runtime but you don’t know what class it will be ahead of time. Maybe its driven by an external data source? You could have a nice if/else or switch block and call the class based on a variable, but that’s a pain in the ass.

So, here is a function that I came up with to make it easier:

function getArbitraryLibraryObject(n:String):Object {
var objC:Class = Class(this.loaderInfo.applicationDomain.getDefinition(n));
var obj:Object = Object(new objC());
return obj;
}
var mc:MovieClip  = getArbitraryLibraryObject(linkage) as MovieClip;

Let me know if there’s an easier way to go about it, but I haven’t run across one.

In my Ramen player, I’m using this to call sound effects and page to page transition effects.

Articulate headaches, pt. 1

So, I had a really time with Articulate today. Something that should have taken 15 minutes stretched into hours due to a few mistakes. Here’s what went wrong and how I fixed it. I received a lot of help from Twitter – links below.

Problem: I needed to update a few Flash movies embedded in a straightforward Articulate ’09 course, then publish and upload. Simple enough, right?

Updating Flash movies embedded in an Articulate course

When you update a Flash movie that’s embedded in an Articulate course, Articulate picks up the new file since has a link to it on the hard drive.  But it wasn’t doing this with the Flash movies that I had. And I couldn’t figure out why – I didn’t want to reimport them all.

So, I tweeted the problem and Dave Anderson replied with a Screenr showing how this is supposed to work. Well, ok – I had the right idea. But I’d forgotten that when I installed Windows 7, I’d moved all of my working files – so the project was in a completely different location than it had been when I created it. Doh! Articulate stores absolute references to embedded Flash, not relative. Moved the files back to where I had them and that problem was fixed.

Dave later directed me to a Screenr by James Kingsley showing good Flash/Articulate workflow techniques.

Presenter locking up when publishing

So, next problem that I had was presenter stopped publishing the deck. It always stopped on the “Saving files to disk” operation. At first it seemed random as to which slide it got stuck on, and then finally settled on slide 18. It just would not go past this point. I rebooted, which has resolved this issue in the past, but no luck.

Back to Twitter. Brian Batt offered to help and directed me to download and run the Articulate debug tracer, and then send the results back to him. With this running I could see that the SWF on that slide was causing the freeze. I republished the SWF. Not fixed. Reinserted the SWF. Not fixed. Deleted the slide and rebuilt it. Still no luck.

Out of ideas, I uninstalled Articulate, rebooted and reinstalled it. I’d seen that anti virus programs can also interfere with this so I turned it off while I was at it. One of these fixed it. Not sure which since I didn’t follow good troubleshooting procedures, but it publishes just fine now. Which is all I cared about.

The trace window is pretty cool – they should include something like this in the tool under a “More Details” button  – I’m not a fan of processes that take >10 minutes to run with little information. This fixes that for me.

Uploading to a FTP site

I uploaded it to my site and went to preview it. I got the dreaded “Slide 100 of 160” blank screen error. This means that either I’m using Articulate 4 with Flash 10 (which I’m not) or something didn’t upload correctly. I deleted the files and tried again. Same issue. Articulate has a built in FTP option, so I used that. It failed twice saying “Cannot upload file, unknown error.”

I’m just a little mad at this point </sarcasm>.

I started looking at options in my FTP program. I noticed that the file transfer type was set to “auto.” I’d seen problems in the past where binary files has been uploaded as ASCII, so I changed it to binary. Re-uploaded and viola!

Lessons learned

So here’s what I got out of this:

  1. Articulate doesn’t use relative paths to imported Flash movies. Don’t move things around!
  2. Turn off your virus scanner if you have problems publishing
  3. Always upload Articulate courses in binary mode
  4. Articulate has awesome support via Twitter

SCOMaster – Gameplay

I was finally able to record a round of my SCOMaster game! Recap – It’s a multiplayer WiiFlash game designed to be played with teams in an instructor lead classroom setting. The object is to assemble a learning program structure the fastest – but watch out, because your opponent can take one of your SCOs and reuse them in their own program. Developed in Flash CS3 in about 150 hours.

SCOMaster Gameplay

AS3 Learning Interactions? What should I do?

Casey’s gone back to school and things are settling down with the new baby, so I’m finding myself with a little free time again. When I posed the Creating a Flash WBT Framework post, I had planned to follow it up shortly with a few learning interactions, but I never found the time. Now I have some of that time. And being inspired by this conversation on the Pipweks board, I think that it’s something that would help out a lot of people.

I don’t plan to make them drop dead simple to use, like the old ones that were included with Flash, but I’d like to ask my (very few) readers: “What would you like me to do?” Are there interactions that you’d like to see?

I plan on making them class based, following the MVC pattern, with the data stored in an XML file. Should make it easy enough to modify, but the AS3 code would be intermediate level so it would require some effort there.

If I don’t receive any comments, I’ll just start wandering in a random direction and post what I come up with.

Update, 1/21/09: Well, things didn’t go as easily as I’d planned. Work was crazy and then I took a break for the holidays and just couldn’t get motivated to start on these. Excuses. But I’ve finally gotten around to turning the computer back on in the evenings, so I’ll be picking up on a few odds and ends soon.

Also – thanks for all of the comments!

WiiFlash Graffiti Gestures

I’ve been playing around with using gestures with WiiFlash as an alternative input scheme. As a first step, I’ve taken the Flash Gesture recognition code from Didier Brun and modified it to work with a Wii remote instead of the mouse. It works pretty well – some of the letters aren’t easy to hit – but not bad for a first try. I’d like to modify with further have more “shapes” rather than “letters” to match. More to come on this when I get extra time.

We had a baby!

It’s been quieter than usual around here be cause on July 9th, our son Gabriel James was born.

Casey went to the hospital with chest pains – and it turned out that she was in labor! After 14 hours of labor, Gabe arrived, 3 weeks early, at 11:21am. He was pretty big at 7lbs 2oz and dispite being early, everything was OK and we went home on time.

Sophie’s getting used to him, and we’re getting used to the two of them.

SCOMaster – WiiFlash mulitplayer learning game

SCOMaster screen shot

After a week and a half I finally finished my first real WiiFlash game – SCOMaster. It’s a competative, 2 player learning game designed to be played in a group setting. It illustrates the concepts of assembling a course in an LMS system. Bonus points are awarded for content reuse – they are SCOs after all! Unneeded objects and faulty objects can be sent back to the development team to be reworked – but at a cost.First one to build a completed activity tree wins.

Ben Hutchens, our graphic designer, created the art work for it. It took about 60 hours to program it using the WiiFlash classes that I had developed earlier in the year.

WiiFlash Tip #4 – Revisiting Wii-mouse in a multiplayer scenario

In February, I posted about using the Wii remote as a virtual mouse in Flash. While that approach seems to work just fine in a simple single player application, I found that it breaks really badly when you another player to it. I just completed my first two player WiiFlash game and I’ll document a few things that I had to differently.

Originally,  based all of the interaction with the cursors off of the typical mouse events (rollover, rollout, etc.), but this did allow for find out which player rollover the sprite or which player “clicked” on the sprite.

Each player’s cursor is just a sprite itself, so I switched to using the hitTestObject function against each players cursor sprite and the object sprite on a mouse event. This returns which of the cursors interacted with the object. Additionally, since the cursor sprites are big, you do have to see them from a distance, I found that I needed to add an additional sprite to the cursor – the cursor “point” – at 0,0 and use that for the hitTest rather than the actual big cursor sprite. If the “tail” of the cursor arrow is still over the object sprite, you shouldn’t count that as a roll over, since the point of the arrow is the important part.

So here are the functions for a rollover:

 private function onItemOver(e:MouseEvent):void {
var wm:Array = whichWiiMotesAreOverMe(Sprite(e.target))
for (var i:int = 0; i < wm.length; i++) {
_WiiMotes[wm[i]].doRumbleSeconds(.1);
_WiiMotes[wm[i]].cursorState = WiiCursorView.CURSOR_POINT;
}
}

// returns array of which wiimote cursors are over the sprite
private function whichWiiMotesAreOverMe(tgt:Sprite):Array {
var a:Array = new Array();
// _WiiMotes is an array of Wii controller objects
for (var i:int; i < _WiiMotes.length; i++) {
if (tgt.hitTestObject(_WiiMotes[i].cursorPoint)) {
a.push(i);
}
}
return a;
}

The functions for a mousedown are:

private function onItemDown(e:MouseEvent):void {
// gets the index of the _WiiMote object that clicked the sprite
var wm:int = whichWiiMoteClickedMe(Sprite(e.target));
}

// returns index of which wii mote cursor is over with the A button down
private function whichWiiMoteClickedMe(tgt:Sprite):int {
var wm:Array = whichWiiMotesAreOverMe(tgt);
for (var i:int = 0; i < wm.length; i++) {
if (tgt.hitTestObject(_WiiMotes[wm[i]].cursorPoint)) {
if (wm.length == 1) {
// simple test if only one cursor is over
if(_WiiMotes[wm[i]].isADown) return wm[i];
} else {
// little harder if 2+ are over, _LastClickWMIdx is the last Wii mote to have pressed a button
if(_WiiMotes[wm[i]].isADown && _LastClickWMIdx==wm[i]) return wm[i];
}
}
}
return -1;
}

This method, while probably not the best way, turned out to work really well in the game.