dezza’s blog - utterings from the dezmonator

multipleinstances.png

I have been forever doing repetitive tasks in the Flash IDE. Just recently I had the prospect of giving a lot of items on the stage instance names. In certain situations this might have indicated a missed opportunity to attach and place symbols dynamically. As it happens, the instances were all different symbols and much easier to position visually than with code. I decided to try and write a jsfl script for Flash that would auto name instances on the stage.

What it does:
Takes selected unnamed stage instances and gives them names based on their library symbol name. Multiple instances that use the same symbol will have numbers added to the name to give each instance a unique name.

To run the script, copy the file into the relevant commands folder of your Flash :

Windows Vista

drive\Users\username\Local Settings\Application Data\Adobe\Flash CS4\language\Configuration\Commands

Windows XP
drive\Documents and Settings\user\Local Settings\Application Data\Adobe\Flash CS4\language\Configuration\Commands

Mac OS X
Macintosh HD/Users/userName/Library/Application Support/Adobe/Flash CS4/language/Configuration/Commands

Mac
/Users//Library/Application Support/Adobe/Flash CS4//Configuration/Commands/

The script can then be accessed from the commands menu in the Flash IDE

Download the script
autoname-instancesjsfl.zip

The script explained:

JavaScript:
  1. // dom - the flash DOM
  2. var dom = fl.getDocumentDOM();
  3.  
  4. // hash to keep store whether a base name will be used more than once
  5. var usedNames = new Object();
  6.  
  7. // hash to keep count of how many times a base name has been used during autonaming
  8. var renamedNames = new Object();
  9.  
  10. // total renamed instances count
  11. var renameCount = 0;

Declare some variables. When autonaming I need to know it advance of giving an instance a name whether it will require numbering as well as it's 'base' name and if so what the count for that base name is already. I use some hashes to store that info: the base names as keys with a usage count as the value.

 

JavaScript:
  1. // return true if instance requires rename
  2. function requiresRename( instance ){
  3.     if( (instance.instanceType == "symbol" && instance.symbolType=="movie clip")
  4.         ||  instance.elementType == "text" ){
  5.         return instance.name == "";
  6.     }
  7.     return false
  8. }

This returns whether or not an instance should be auto named. I did a bit of experimentation on what sort of properties items that could have instance names were to generate the appropriate values. I added a clause for textfields as well, but I wasn't able to figure out how to distinguish dynamic text fields from static text fields so the script might not work properly if static text fields are in the selection.

 

JavaScript:
  1. // return true if name is used more than once
  2. function hasMultipleInstancesOfName( name ){
  3.     return usedNames[ name ]> 1;
  4. }

Checks the usedNames hash to see if a base name has been used more than once. I use this later to decide whether or not to auto number instances that share the same base name.

 

JavaScript:
  1. // update a hash with names and usage count
  2. // names as keys and usage count as value
  3. function addToUsedCount( dict, name ){
  4.     if(! dict[ name ] ){
  5.         dict[ name ] = 1;
  6.     } else {
  7.         dict[ name ] ++;
  8.     }   
  9. }

This increments one of the usage count hashes for a name.

 

JavaScript:
  1. // get base name for instance
  2. function getBaseName( instance ){
  3.     // use library item name if possible
  4.     if( instance.instanceType == "symbol"){
  5.         var s = cleanName(instance.libraryItem.name);
  6.         // make first letter lowercase
  7.         var s1 = s.substr(0,1).toLowerCase();
  8.         var s2 = s.length == 1 ? "" : s.substr(1);
  9.         return s1 + s2;
  10.     } else {
  11.         if( instance.elementType == "text" ) return "txt";
  12.         return instance.elementType;
  13.     }
  14. }

This generates base names from the library symbol's name for mcs and just 'txt' for text fields. I also force the first character to be lowercase to follow the convention for instances.

 

JavaScript:
  1. // very basic string clean
  2. function cleanName(name){
  3.     var n =  name.split(" ").join("");
  4.     // remove any path parts before name
  5.     if( n.indexOf("/") != -1 ){
  6.         n = n.substr(n.lastIndexOf("/")+1);
  7.     }
  8.     return n;
  9. }

Simple cleaning of symbol names for use as instance names i.e. remove spaces. I name my symbols reasonably sanely so didn't look for much more that would create invalid instance names, such as symbol names that start with numbers for example. I leave more robust cleaning up to the reader.

 

JavaScript:
  1. // iterate over selection and autoname instances 
  2. if(!dom.selection.length){
  3.     alert("Please select instances(s) to name");
  4. } else {
  5.  
  6.     // first pass to check if any instances names require numbering
  7.     for( var i = 0; i<dom.selection.length; i++){
  8.    
  9.         var instance = dom.selection[i];
  10.    
  11.         if( requiresRename(instance) ){
  12.             var baseName = getBaseName( instance );
  13.             addToUsedCount( usedNames, baseName );
  14.         }
  15.     }
  16.  
  17.     // second pass to rename instances (in reverse to respect selection added order)
  18.     for( var i = dom.selection.length -1; i>= 0 ; i--){
  19.  
  20.         var instance = dom.selection[i];
  21.    
  22.         if( requiresRename( instance ) ){
  23.             var baseName = getBaseName( instance );
  24.        
  25.             if( hasMultipleInstancesOfName( baseName ) ){
  26.                 addToUsedCount( renamedNames, baseName);
  27.                 baseName += "_" + renamedNames[ baseName ];
  28.             }
  29.        
  30.             instance.name = baseName;
  31.        
  32.             renameCount ++;
  33.         }
  34.     }
  35.  
  36.     alert( ""+renameCount+" object(s) renamed");
  37. }

This is main renaming script. It iterates over the selection twice. The first pass essentially decides whether automatically generated names would be used more than once. The second pass than applies the names to the instances, updating the counts as it goes so the auto numbering can be added if required. I found that iterating backwards in the second pass meant that items would be numbered the right way based on selection order.

Finally a little message to display the total rename count.

(2 comments)

Thanks for dropping in. Are you getting tired yet? I hope you're enjoying it. I had a hand in making this so I hope is going all right for you. Please leave a comment and let us know how you're going.

Noticed anything different lately? We've been beavering away behind the scenes to make some last minute improvements for racers. You should now be able to see up and coming prize tokens and rainbows on the thumbnails for the next sites.

If you need some tips, Mattias wrote some good pointers on his blog, they are right on the money. The worst thing that can happen is that you get stranded without boost, so I recommend that you only put your foot down when you see some more coming up.

Happy boosting!

Update: We've fixed that annoying "your balloon has left..." screen appearing twice if you had left the computer for a while. Now when you follow your balloon you should go straight to it :)

(8 comments)

We have just deployed the mega-beast at www.playballoonacy.com.
Our game is in your internet suckas.

screenshot of the balloon race

(no comment)

This is the first phase of the latest project I've been working on at Poke, a flash site for Orange www.playballoonacy.com. Finally the big clients are letting us use AS3 (Flash9). This project is massive. Thankfully, I'm getting some help from Gabes aka Pixelbreaker. Get a balloon or submit your site to be part of the race.

(1 comment)