Tag Archives: flash

as3 dec <-> hex

Actionscript suffers like many other languages from poor string parsing commands. What would take one line of well crafted perl is… a bit more complex here.

[as3]
public function hex2dec( hex:String ) : String {
var bytes:Array = [];
while( hex.length > 2 ) {
var byte:String = hex.substr( -2 );
hex = hex.substr(0, hex.length-2 );
bytes.splice( 0, 0, int("0x"+byte) );
}
return bytes.join(" ");
}

private function d2h( d:int ) : String {
var c:Array = [ ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’ ];
if( d > 255 ) d = 255;
var l:int = d / 16;
var r:int = d % 16;
return c[l]+c[r];
}

public function dec2hex( dec:String ) : String {
var hex:String = "0x";
var bytes:Array = dec.split(" ");
for( var i:int = 0; i < bytes.length; i++ )
hex += d2h( int(bytes[i]) );
return hex;
}
[/as3]

What do these methods do? Well, hex2dec takes a hexadecimal string (and assumes you have a throwaway prefix of “0x” or “#”) and returns a space-separated list of decimal values. dec2hex does the same thing, but in reverse.

hex2dec("0xF00F04") returns “240 15 4”.
dec2hex("240 15 04") returns “0xF00F04”.

Also, the method doesn’t much care if you’ve got 6 hex digits or 60.

There are a few optimizations I could make on this code here, but it’s not getting called that frequently anyway. The performance gains in my application would be trivial.

And just by way of warning, this is AS3 code. It’d need a few tweaks to work reliably in AS2 or (shudder) AS1 environments.

update – may 7, 2008

It has come to my attention that people keep stumbling across this old post. While I don’t have the time or interest to optimize these functions for real environments in any of the several ways they could be improved… I figure I’d take a moment for the benefit of those who are probably just looking for the quick answer.

The easiest way of getting a hex string from an int value is to call its toString() method with a radix argument of 16. Likewise, you can request any integer base from 2 to 36. Results use lower-case letters when outputting in a base higher than ten.

240.toString(16) returns “f0”.
240.toString(8) returns “360”.

slideshow

Several months ago, I wrote a very simple Flash slideshow application for work. Shortly after that, I took some of my free time and built a similar application from the ground up. This time, I got to choose my own spec 😉 I’d always promised that I’d release the thing to the public, and last night, Peter asked for the source. Embarrassment ensued when I realized that I’d never gotten around to making that public release. Well… that changes now.

The whole application is about 130 lines of code plus Joey Lott’s ascb.util.Proxy class. I did this all back in AS2. When AS3 came along, I decided that I’d eventually rewrite the slideshow again and release it along with full source (GPL or similar). Haven’t had a chance to do the AS3 rewrite yet (even though I have written a different slideshow in AS3 since then… :P). Until the time comes for the AS3 rewrite, I’ll keep my ugly code to myself.

To view the slideshow in action, go here.

license issues

Obligatory disclaimer goes here. I’m not responsible if using this component causes your children to hate you, your dog to die, your house to burn down, or your hair to fall out. Or anything else for that matter. You have been warned.

I’m not releasing the source right now because I don’t feel like cleaning it up. Feel free to try to decompile the SWF if you really want to, but I’m warning you, it’s really probably a waste of time.

Please download the SWF to your own host and use it from there in stead of loading it from my machine. It’ll work better for everyone involved that way.

Otherwise, feel free to use the slideshow however you want. I’d appreciate a credit for it, but otherwise am not picky.

features

The slideshow will work on any computer with Flash 8 or newer installed. As of Sept of 2006, the numbers say that about 90% of net connected computers in the US, Europe, and Japan meet the requirement.

The application loads images externally. This means that the entire SWF is able to weigh in at under 4kb. The images you’re going to be rendering will likely be significantly larger than that. The slideshow begins once the second image is loaded, so even on slower connections, things will start rolling w/o a need to pre-load every image. If an image isn’t done downloading by the time the slideshow reaches it, it’ll just loop back to the beginning.

You can customize the delay between images in the HTML/Javascript you use to load the SWF. There are no fancy transitions to worry about choosing between and configuring, the images just cross-fade.

You can specify your list of images either via an external XML file or by embedding it in the HTML of the page itself (and using some Javascript magic that I’ll explain later).

instructions

First off, I have to make the disclaimer that I am a firm believer in FlashSWFObject. I will assume for now that you’re using it too if you have the chance. I’ll think about trying to explain how to make things work in MySpace and other crippled environments later (like not today).

  1. Make sure you have a modern version of SWFObject and the slideshow component.
  2. Build a list of the images you want to display.
  3. Put everything on the server.
  4. Mix it all together.
  5. Point people at your slideshow.

getting your stuff together

At the time of this writing, Geoff hasn’t made a SWFObject release in a while, but any time you’re planning on using it, it’s always worth looking to see if he’s somehow streamlined/upgraded the script since the last time. Download SWFObject.

I’m not planning on making any improvements to this version of my slideshow, so there isn’t any reason to check for updates from me. Download Slideshow. Unzip it. Yes, I realize that by zipping this file I have made it larger. I zip it in order to make downloading the file easier.

It’s generally recommended that you crop all of your images down to the same size. The slideshow just aligns everything to the top left corner of the SWF. So large images will be cropped and small images won’t fill the whole area.

Upload everything to the server. For my demo, I copied everything into a /slideshow folder and put the pictures in /slideshow/images.

write your image list

Whether you’re using an external image list (an XML file), or you want to embed the image list into your HTML and extract it with Javascript, you need to come up with a list of the images in question and the order in which they’re to be loaded. The format for an external file looks like this:

Painless enough, right? You can use relative paths (relative to wherever the SWF resides) or absolute URL’s, just as if they were image links in an HTML document. Now upload the XML file to somewhere that your SWF can see it (ideally on the same server, probably in the same directory). I put mine at /slideshow/images.xml in the example.

write your html

To put it all together, you want your html to look something like this:

Ok, that’s not the entire file, those are just the relevant bits. This is also not a SWFObject tutorial, so I won’t explain exactly what’s going on here. The important things to look at are the config variables at the beginning of the javascript block, which should be self explanatory. Load up the HTML file and if you did everything right, it should work quite happily.

extra credit – embedded image list

The data format for the image list is essentially identical if you’re embedding the list in your HTML, except you swap the images tag out for a div with an id (for html validity reasons, really):

This can go anywhere in the SWF, as long as it’s before the script tag where you do your SWFObject magic. Ideally, you’re just re-using the div that SWFObject is going to replace.

Then, you need to do some slightly different javascript when loading SWFObject. I did something more like this:

Again, I won’t explain exactly what’s going on here, but for those programmers out there, it should be pretty obvious. The one major difference between this embedded approach and the external one is that we’re using the slideshow div to hold the image list and are handling our error message manually.

Why go through the hassle to embed your image list? Well, it’s a tough call. But this way does load faster, especially if your server gets caught up trying to deliver the external XML file.

caveat – crossdomain security

I don’t really want to go into this whole issue, but should probably warn you about it. As of Flash 7, security improvements in the player make it a hassle to load files (images, xml, etc…) from remote servers. By remote, I mean somewhere other than wherever the SWF was loaded from. For more information on how to deal with this problem, take a look at Macrodobe’s tech note on the subject.

flash audio timeline confusion

Audio synchronization in Flash has always been something of a black art. It’s a lot better these days, but there are still some interesting glitches floating around.

I’ve currently got a doozy of an issue in a project that I thought I was done with over a month ago 🙂

There are two and a half ways to manipulate sound in Flash.

  1. You can just drop audio tracks onto the timeline and hope for the best.
  2. You can instantiate Sound objects in, attach the audio tracks, and play them.
  3. A hybrid method where sounds are loaded onto the timeline but are then manipulated with a Sound object.

In 90% of cases, my game uses the second method. In the other 10%, I used the third. I have a simple flag (stored at _global.audio) that is set to true if people want sound playing and false otherwise. Any of my sound handling code monitors changes in the flag and sets volume on the appropriate sound objects accordingly. Nothing too fancy.

However, we’ve found an interesting fringe case when trying to control timeline sounds via actionscript. To duplicate the problem:

  • Take one stage with a 2 frame timeline and one movie clip.
  • On the movie clip, load a sound onto the timeline.
  • Put the clip onto frame 2 of the stage, leaving frame 1 empty.
  • Put a stop() action on the second frame of the main timeline.

This works as intended – ie, the sound plays exctly once.

  • Now, add some code to the movie clip’s timeline to control the volume:
    [as3]
    var snd:Sound = new Sound(this);
    snd.setVolume( 0 );
    [/as3]

This also works as intended – ie, the sound does not play at all.

  • Replace the stop() action on the main timeline with a gotoAndStop(1) call.

Now if you play the swf… the sound will happen… even though we’re explicitly telling it not to – and you’re jumping to a state where the movie clip containing the sound should not be loaded.

I suspect that what is happening is that when you leave the portion of the timeline where the Sound object exists, there is a bit of confusion in the VM. In stead of discarding the movie clip in its entirety as makes sense, it’s discarding the sound object first. The timeline then continues playing the audio where it left off (after being muted for only one frame).

So… if you want reliable control over your audio assets, the solution might then be to put your Sound object responsible for playing them in a location where it won’t be destroyed when the timeline updates. Unfortunately, that doesn’t seem to work either. I’ve tried locating my Sound object in _global or _root, but that doesn’t solve the problem either.

What appears to happen is that sounds on the timeline are attached to the stage when their individual timelines disappear. Telling my Sound object to listen to the stage in stead of to the movie clip works.

I’m investigating this more… maybe… but shrug. More likely, I will simply find a way to stop using sounds on the timeline at all in this one problem spot in the game. 😛

wii for flash

Ok, so I’m biased/interested because I write Flash for a living. But that doesn’t change things.

It’s been announced that the Wii is getting Opera. This is wonderful. They’re not just getting Opera, they’re getting a full blown non-wimpy version (as opposed to what I have on my cellphone).

As part of the bundle, this means two huge things that have never been done (or at least haven’t ever been done well) on a television-screen type web appliance. Opera by itself already has decent enough Javascript support, meaning all sorts of loverly AJAX content is gonna work in the living room. There is already a video on YouTube of somebody browsing Google Maps on a Wii, for example.

The other huge thing is Flash support. And this is where I am both stoked beyond measure at the possibilities this opens up to me personally as a developer (and for my industry and for the future of the internet as a whole – think homegrown flash wii game community) and am terrified at the one big thing they keep failing to mention.

Nobody’s ever said what version of Flash the Wii is gonna get.

It’s like they’re avoiding the question.

See… if by Flash they mean latest and greatest Flash 9 support, I’ll be pre-ordering the console despite my reservations about the dumb controller that they’re gonna try to make me use 😛

But I don’t expect that they’re actually gonna get Flash 9. At least not at launch. I could hope for Flash 8, but I seriously doubt that one too. Yup. I’m guessing they’ll launch with 2003-era Macrodobe Flash 7 support. Why?

  1. If they were gonna launch with Flash 9 support, they’d be announcing it at every possible chance. That they’re being so tight-lipped as to specific versions…
  2. Macromedia never ported Flash 8 to Linux. Adobe probably won’t be releasing 9 for Linux until next year. While the Wii isn’t running Linux, it certainly ain’t a Windows or OSX box.
  3. Adobe hasn’t ported to any exotic architectures in a while. The SPARC got Flash 7, but that’s as fancy as it gets. It’s otherwise just been Intel and PowerPC based chips to get the releases. The Revolution is running on something completely new.
  4. And the clincher. Opera recently (like not quite 3 weeks ago recently) acquired rights to distribute the Flash 7 SDK as part of their Opera for Devices distro.

Soo… future potential?

I’m guessing that there won’t be another Flash 8 release, so our only hope is that they’ll get around to making the big jump to Flash 9. Eventually.

I mean, Opera’s just a program that you download onto the Nintendo, so it should be subject to patches and upgrades. I’m a bit worried that one of the reasons for the application’s initial launch as a free program (until next summer) is a way of covering while they either dev on the Flash 9 port or pretend that it’s not gonna be a problem.

But it is.

Current (as of last summer) Flash version penetration numbers say that 85% of internet connected computers worldwide have Flash 8. That’s a lot of computers. Flash matters. No numbers are out on Flash 9 yet, but adoption is rapid and version upgrades are painless, so I expect it’s pretty close.

It is going to take some people time to switch over to Flash 9, but my workplace is already switching over major new projects to the platform. I know from personal experience that Three Rings is using Flash 9 for their next game (of which they’ve not really released much information to the public yet so I’ll be nice and not blab – but their front page does look like they’re getting ready to link to stuff any day now). MySpace is requiring users to upgrade to Flash 9. Etc…

If it isn’t necessarily a compatibility issue at launch time, it will certainly be a problem within a year. It’ll become the equivalent of trying to view modern web pages in Netscape 4. Adapt or be devoured and all that.

xpath

Yargh!

I’m currently involved in some very heavy manipulation of XML data in a Flash application. For such purposes, I am compelled to use XPath. It’s a decent enough language. Ok, I lied. It’s good. Saves mounds of time that would otherwise be spent iterating over xml tree structures and searching for elements.

When using XPath in Flash, one has two options. First, Macromedia Adobe has a first party implementation. Apparently it’s not that wonderful and nobody who knows better uses it. Second, there’s the XFactor Studio API. This is what I use. It’s what a lot of people use. It is nice. It has never failed me before.

Until today.

I have a very simple favor to ask of the library. I want to select all of a node’s siblings. Now, granted, I am doing some searching to determine which node’s siblings I need here, but it’s really basic.

The XML doc I’m working with looks something like this:

What I want is all <choice>’s in the same <group> as a <product> with a given <p>. Sound simple enough? Well, it is. The XPath statement to do this might look something like this:

//group[products/p='3']/choice
or
//group/choice[../products/p='3']

Both search paths are equally valid and return the same results when I try them out on other xpath implementations.

The XFactor version returns nothing. I know the lib works, and I know I’m using it correctly since my program continues to function up to this point (and I’m making 4 or 5 selections before this point).

So, I’m mildly peeved here. I’ve tried breaking it up into a pair of sequential queries (first select the appropriate group, then select the choices within that group), but that doesn’t do anything either.

So far, this problem has cost me 2 hours this morning and it doesn’t look to be clearing up any time soon. Sigh.

update

After another hour, I have determined that the XFactor XPath implementation is broken when it comes to searching based on text node values. Chris (coworker) swears up and down that it isn’t broken, so he’s trying to prove me wrong now 😛

In the mean time, I have implemented an ugly brute-force solution to the problem. So, in stead of:
[as3]
var path:String = "//group/choice[../products/p=’"+pid+"’]";
var list:Array = XPath.selectNodes( configurator.firstChild, path );
[/as3]
I have had to settle for something like this:
[as3]
// grab all products
var path:String = "//group/products";
var pNodes:Array = XPath.selectNodes( configurator.firstChild, path );
var gNode:XMLNode = null;

// iterate over products until we find the one we want, YICK
for( var k = 0; k &amp;lt; pNodes.length; k++ ) {
// look at all <p/> children
var tmp:Array = pNodes[k].childNodes;
for( var j = 0; j &amp;lt; tmp.length; j++ ) {
if( tmp[j].firstChild.nodeValue == pid ) {
// parent.parent 🙁
gNode = tmp[j].parentNode.parentNode;
break;
}
}
if( gNode != null ) break;
}

// grab the appropriate wad of choices, finally
var list:Array = XPath.selectNodes( gNode, "//choice" );
[/as3]

update

After about 20 minutes of headscratching, Chris seems to have given up as well 🙂

Interestingly enough… the first party api doesn’t do it either:
[as3]
var path:String = "//group/choice[../products/p=’"+pid+"’]";
var list:Array = mx.xpath.XPathAPI.selectNodeList( configurator.firstChild, path );
[/as3]
So… I’m very curious if anybody actually does these kinds of searches in Flash? They’re valid according to the W3C spec and they work in Java… for a language like Flash (which is currently handcuffed to XML as its only reasonable means of communication with the outside world) to have a broken XPath implementation is… not good. Sigh.

frash

I guess it’s something like official? I’m a Flash developer now. Kind of.

At least, I spent all day writing ActionScript today. It looks and feels like a slightly wonky version of Java. What did I accomplish? I have a simple application that reads in a bunch of XML data, parses the heck out of it, and functions as a rudimentary search engine (via an XPath API class). It’s really quite ugly, but the point of this exercise is the functionality, not the prettiness or efficiency.

Give me a few more weeks before I start playing around with stuff pretty enough to show off.