Archive for the 'Flash' Category

Macromedia Components & Object.prototype Don’t Get Along

In most of my flash projects I have a prototype file I include into the project. It contains additions to core objects such as Object, MovieClip, etc. Well, today I found out that some Macromedia components (ComboBox was the one I was having trouble with) don’t like additional methods to be defined on certain classes (Object was the one I found that ComboBox was having issues with); they fail to continue to work with additional methods defined.

However, there is a workaround: ASSetPropFlags. Simply hide all additional methods with this line of code:

ASSetPropFlags(Object.prototype, null, 1);

I can’t wait until AS3 can be used all the time.

Flash & Fonts

I’ve written about the pains of fonts in flash before; and it something that still plauges my work today. However, since that post new tools have been created, new workflows introduced, and with that some new findings.

Fonts With SWFMILL

SWFMILL is an awesome tool that may allow you to leave the Flash IDE untouched for some projects. However, embedding fonts seems to be scarcely documented (I had trouble getting the methods documented working). Here are the two links I’ve found that document embedding fonts with swmill:

I wasn’t able to get embedded fonts working using the information above, so here is my method. This is what my swfmill xml looks like.

FontFile.ttf must be referenced relative to the location of the swfml file, and must be a TrueType font for swfmill to read it successfully. If you want to use a non-TrueType font convert it to a TrueType font with a tool such as FontForge (works great and its free, but has a horrific UI).Now if you create a NavButton class that looks something like this:

class NavButton extends MovieClip {
private var oTitle:TextField;

function NavButton() {
super();

oTitle.selectable = false;
oTitle.multiline = false;
oTitle.wordWrap = false;
oTitle.textColor = 0xFFFFFF;
oTitle.autoSize = true;
oTitle.text = "This is a title";
}
}

And attach the NavButton to the stage using

attachMovie()

you should see the text come up. Note: you don’t need to set

oTitle.embedFonts = true;

to make this work correctly! Actually, dont use

embedFonts

at all!

You may have noticed the properties that I had to set on

oTitle

, this will be different for every situation. It seems that swfmill sets a bunch of default properties when creating a textfield. As a reference, here is the output from

dumpObject(oTitle)

(dumpObject() is a method from my debug class):

styleSheet:undefined
mouseWheelEnabled:true
condenseWhite:false
restrict:null
textHeight:48
textWidth:54
bottomScroll:1
length:12
selectable:true
multiline:true
password:false
wordWrap:true
background:false
border:false
html:false
embedFonts:true
maxChars:null
maxhscroll:0
hscroll:0
variable:null
htmlText:hello world!
type:input
text:hello world!
autoSize:none
tabIndex:undefined
textColor:0
backgroundColor:16777215
borderColor:0
maxscroll:2
scroll:1
filters:undefined
sharpness:undefined
thickness:undefined
antiAliasType:undefined
gridFitType:undefined

Shared Fonts in Flash IDE

Shared fonts, especially shared pixel fonts, are tricky business in the Flash IDE. Sometimes I wonder if it’s worth the effort, and whether I should just embed the fonts in each SWF. Alot of times I get blurred text when loading the pixel font from a shared library, but no blurring if the font is embedding in the swf itself. Shared fonts seem to work well with non-pixel fonts though; so if you dont need pixel fonts I would definitly use shared libraries. If you are looking at using shared fonts in your project I would recommend checking out Shared Fonts Manager.

AttachMovie & Loaded Clips

Using

attachMovie

when you’ve loaded other clips into your movie has always been very painful.
You can’t

attachMovie

a asset into a loaded clip that is located in the parent movieclip, and conversly you can’t

attachMovie

a asset in a parent that was loaded into a child.

This is extremely frusterating… but after some searching today I came across this interesting link. Using the fact that Flash likes to cache everything it can, he created a function that will load an clip that contains an asset into the movieclip you are trying to use

attachMovie

from.
Nice idea, never thought of doing this before.

Note: this is only needed if you are loading external movieclips and want to use common assets, yes you could use shared assets but they have always given me a headache (they are a pain to create/maintain, although they may have improved since I’ve last used them), and this seemed like an interesting alternative.

Update:
After attempting to use the above mentioned method I found that the code on the site I linked to wasn’t really usable for what I was trying to do, I rewrote it a bit:

/*
 Function: attachMovieAnywhere
 
 Description:
 Loads a clip (should have nothing on the stage, containing just assets) and attaches a movieclip from the loaded clip onto the stage
 
 Arguments:
 file - [String] path to the SWF containing the assets
 callBack - [Function] function that will be called once the asset swf is loaded, and the movieclip has been attatched. The scope of the function is the attatched movieclip, and the first argument is the attatched movieclip.
 If you need a different scope use the <delegate> class.
 NOTE: this does not call once the attatched movieclip has been initialized, only when it has been attatched!
 */

MovieClip.prototype.attachMovieAnywhere = function(file:String, idName:String, newName:String, depth:Number, initObject:Object, callBack:Function) {
    if(depth == undefined)
        depth = this.getNextHighestDepth();
   
    var parent:MovieClip = this;
    var container:MovieClip = this.createEmptyMovieClip(newName, depth);
    var mcLoader:MovieClipLoader = new MovieClipLoader();
    var listener:Object = new Object();
   
    listener.onLoadInit = function (mc) {
        parent[newName] = mc.attachMovie(idName, newName, mc.getNextHighestDepth(), initObject);
        if(callBack) callBack.call(parent[newName], parent[newName])
    }
       
    mcLoader.addListener(listener);
    mcLoader.loadClip(file, container);
}

Here is some example code showing how it is used:

attachMovieAnywhere("asset.swf", "aAsset", "coolthing", getNextHighestDepth(), {_x:-40, _y:-40}, function(mc) {
    if(mc == this) {
        // mc == this unless you use the Delegate class to change the this var
        trace("They Do!")
    }

    // you can do initialization here
    mc.onRollOver = function() {
        trace("over").
    }
   
    mc.onRollOut = function() {
        trace("out")
    }
});

Adding Methods to Core Flash Classes

Every once in a while I get an email that looks like this:

I tried using your Object, Function, and String method additions. When I tried to compile I get a bunch of error messages! What do I do?!

Yup, this is because the method definitions are not in the Class definition files that flash looks at when compiling. The core class definitions that Flash looks at are located here:

~/Library/Application Support/Macromedia/Flash MX 2004/en/Configuration/Classes

That “Classes” folder will contain all the method definitions for all core Flash classes (MovieClip, Object, Button, Color, etc).

To make my method additions compile correctly you’ll have to edit the corresponding Class definition files and add the method definitions in. So, for instance, if you wanted to use the object.as additions you would add these method definitions to your Object.as file in the “Classes” directory referenced above:

function initBroadcaster();
function addEventListener();
function removeEventListener();
function dispatchEvent();
function centerXY(x:Number, y:Number):Void;
function centerY(y:Number):Void;
function centerX(x:Number):Void;
function isInstanceOf();
function isMemberOf();

If you are using Flash 8, they will be spread out in two different directories “FP7″ & “FP8″ located in this directory:

~/Library/Application Support/Macromedia/Flash 8/en/Configuration/Classes

If you use mtasc you’ll have to edit the class definitions located in the “std” directory.

XASH 1.2

XASH 1.2 has just been released. This release has the following enhancements.

  • Fixed a nil URL bug
  • Added live (itunes-like) searching
  • Some code cleanup/reorganization
  • Added drag n’ drop for adding additional search paths
  • Added the sparkle update framework

Enjoy!

If your a Cocoa developer you may want to check out XASH’s source code, it has a nice implementation of enabling a NSTableView to have a drag n’ drop capabilities while still using NSArrayController to populate the table.

XTrace: Flash Debugging Without The Flash IDE

XTrace 1.0, a replacement for the horrible trace window in the Flash IDE, was released a few days ago. Take a look at the product page for more information on how it works and how to integrate it into your flash application. This is one of the pieces to the puzzle, I’ll release the BASH script I’ve written that allows better MTASC Xcode integration as soon as possible.

I need more beta testers for the new application I’m going to be releasing, email me if your interested!