Setting the swf Base Directory in HTML

Have you ever completed a flash project and started testing it online only to realize that the swf is looking for assets either in a different directory than the one you specified? Or that the folder that you have all your media stored is not in a relative directory like it was when working on it locally?

The solution that I mustered up in the past was to create a flashvar called something like “mediafolder” and put that in the embed code. From there, I would go back into my actionscript code and make sure all external media had the passed “mediafolder” variable appended to the beginning of the url for each external asset and then republish my swf.

This always worked well, so I usually plan for this, but my latest project didn’t have that built in. When it came to testing and we realized that the media folder was going to be in a different location than the base swf file and it was supposed to launch soon, it was time to see if there was another alternative to the usual solution. That’s when I discovered the “base” attribute in the swf object embed code.

The “base” attribute is actually an href attribute that specifies a base URL for all relative URLs on a page. Traditionally, you should be able to put it in the head of an html page and have all links on a page link relative to the string specified in the base attribute. For this it’s just specified for the swf, which picks it up when passed as a param and picks up any external asset from that folder by default instead of the folder that the actual swf is in.

Here’s a sample of the swfobject embed code:

 

With the example above, any asset that the main swf is trying to load relative to itself can now be placed in “../project/subfolder” without having to change any actionscript and republishing your swf. This is a tip that has saved me hours of work and would have saved me even more time had I discovered it in the past.

Loading External Across Domains in Flash

I feel like I’ve run into this issue so many times and either fixed it by accident or came up with some other solution in order to do the same thing. This time I cam to a conclusion that I understand and hopefully other people can use.

The Problem:

You create an flash app for the web which loads in data from a variety of other external sites, such as thumbnails from an aggregated feed using a 3rd party API and it works swimmingly while you’re testing locally. As soon as you put it on a remote server, you get a Flash Player security error, perhaps something like:

SecurityError: Error #2122: Security sandbox violation: LoaderInfo.content:http://staging.site.com/project/Main.swf cannot access http://www.website.com/image.jpg. A policy file is required, but the checkPolicyFile flag was not set when this media was loaded.
    at flash.display::LoaderInfo/get content()
    at com.gregkepler.testProject.imageloader::ImageLoader/onImageLoad()

Depending on if you’re ready for this error or not, you may not get a popup and can fail silently.

Why This Happens:

This is happening because you don’t have your policy files set up on your server and your swf is “illegally” trying to access data from another domain. This is actually a good thing since it stops potentially dangerous files from doing bad shit to your project/server/network/computer. But you want to ALLOW access to these different domains since that’s a big part of your project, right? The solutions are actually very easy to implement, just sometimes a pain in the ass to figure out.

The Solution(s):

Depending on the project and how wide-spread and prominent it will be on your website and if other projects will need the same sort of access on your server, you may want to allow the entire domain access to the external domains or just one individual project.

For an entire domain

All you have to do is place a crossdomain.xml file is the root of the server where the project will reside. The crossdomain file will look similar to this:

  

Replace the * with a specific domain if you don’t want to allow access to all sites. This works because the flash player automatically looks for a crossdomain.xml file when it is asked to load any file in a different domain. It checks to see if it should allow the file based on which domains are specified in the file. If it doesn’t see this file or a domain isn’t listed, or * isn’t specified, it will throw an error and won’t allow the file to be loaded into your app.

For a sub-domain

Sometimes the above solution isn’t appropriate, especially for a website that can potentially house many different projects that have different rules about what is can and should allow. This solution involves a few extra steps, but is still pretty easy.

Step 1:
You still need to add a crossdomain.xml file to the root of your server, but instead of allowing all domains to be accessed, you want to tell it that it should allow crossdomain policy files to be set elsewhere on the server. This is what the crossdomain.xml file would look like instead:




Step 2:
Create a crossdomain file somewhere else on the server that makes sense, such as where your project exists. This will look a lot more like the original file. In fact it’s exactly the same, unless you want to change the domains that you want to allow for this specific project.




Make note as to where you are putting this file, since you will be specifying this actual xml file as the one to look at for cross domain access (ie: http://staging.site.com/project/crossdomain.xml).

Step 3:
The next 2 steps involve actually adding some as3 code and republishing.
Specify the policy file that should be loaded instead of the one in the root. This should be done before trying to actually load anything. I normally place in the document class as one of the first things that should be done.

Security.loadPolicyFile('http://staging.site.com/project/crossdomain.xml');

Don’t forget to import flash.system.Security.

Step 4:
Go to where you are trying to load the external data and create a LoaderContext instance.

var context: LoaderContext = new LoaderContext();
context.checkPolicyFile = true;

As noted from adobe’s website, what checkPolicyFile does is specifies whether a cross-domain policy file should be loaded from the loaded object’s server before beginning to load the object itself.

Then you will pass that context as an argument when you go to actually load the file, as seen below.

imgLoader = new Loader();
iimgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad, false, 0, true);
imgLoader.load(new URLRequest(thumbUrl), context);

This article got me on the right foot: http://stunnedgrowth.livejournal.com/4540.html
More about LoaderContext: LoaderContext

GridFitType

Sometimes, you need to use a dynamic textfield in flash where it’s necessary or more convenient to create the textfield completely dynamically (not placed on the stage in a movieclip in the library). You style your text nicely and set up everything so that it looks just right and then when you go to animate it, the animation looks very rigid and jaggy. This issue is most likely the result of the gridFitType property.

GridFitType is a textfield property that controls how a textfield’s anti-aliased pixels appear within the the stage’s pixel grid. When the textfield is resizing, it’s pixels might be forced out of the flash stage’s pixel grid, which in turn may force a word to move over to the next pixel, which in turn can force it down to the next line if it’s close to the edge. It also makes it so that when animating, each pixel rounds out its position to the next full pixel instead of letting it smoothly animate between pixels, creating the jagged looking motion

The solution to this jagged pixel animation issue is to change the gridFitType property to either NONE or SUBPIXEL. When the textfield is created dynamically, the default gridPixelType is set to PIXEL, while when created through the IDE it’s set to NONE. Below is an explanation of the three options below according to the Adobe AS3 livedocs here.

The 3 available options are:

  • NONE– This specifies no grid fitting and provides for the smoothest animation. This is the default when a new textfield is placed on the stage through the IDE.
  • PIXEL– This specifies that strong horizontal and vertical lines are fit to the pixel grid. This setting works only for left-aligned text fields. This setting generally provides the best legibility for left-aligned text. This is the default for dynamically created text fields.
  • SUBPIXEL – This specifies that strong horizontal and vertical lines are fit to the subpixel grid on an LCD monitor. The subpixel setting is generally good for right-aligned and center-aligned dynamic text, and it is sometimes a useful trade-off for animation versus text quality.

In order to take advantage of the GridFitType property, the textfield’s anti-alias property is set to ADVANCED. Otherwise, it will use the default gridFitType property.

The examples below show how the default textfield plus the 3 types affect the text when it’s being resized. As you can see, setting it to NONE is the smoothest, while PIXEL is the most readable. Setting it to SUBPIXEL is best when you need something more readable than none and smoother than PIXEL.

[swfobj src=”http://www.thegrego.com/wp-content/uploads/2010/02/GridFitType.swf” alt=”This shows how the default and the 3 types of gridFitTypes when applied to a textField that is created dynamically and has animation applied to it.” width=”400″ height=”340″ align=”center” allowfullscreen=”false” required_player_version=”10″]

WordPress Stylin’

This post is for those of you that are intimidated by the idea of styling your first WordPress Blog (if there are any). I’m here to say that I’ve survived and this is the outcome.

During college the whole web development thing frustrated me and scared me enough that I vowed that I wouldn’t touch it again. And since I LOVE flash development so much, I figured that it didn’t really matter. The whole cross browser/ cross platform thing pissed me off and flash allowed me to make something and have it look AND behave the same way every time (almost). Over the past year and a half as I’ve gone more into a development centric career, I decided to give it another go and realized that it’s not so scary. After all, I’ve done a lot of things with actionscript that were way harder to code than a simple CSS/HTML site.

After warming up on some small projects and working my way through a CSS book, I got going with WordPress. There were definitely things that really confused me, but I feel like I learned a lot. The following are some of he snags I ran into that will hopefully come in handy for someone else.

Lessons Learned

There’s a difference between wordpress.com and wordpress.org
Wordpress.com will allow you to have a blog that’s hosted through wordpress.com, but has limited support for styling and using plugins, but it’s free. WordPress.org is free too, but you have to have your own web space and access to a MySQL database so that you can install wordpress on your server and upload your custom theme as well as have a place to store all of your content.

Running XAMPP and installing wordpress locally is key
I’ve had XAMPP on my computer for a long time knowing that I should, but never quite understood it’s usefulness, until now. Since WordPress is run in a PHP environment, every page is a PHP file, which you can only view if it’s online or running in some other server-side environment, enter XAMPP. I’m sure that now that I understand XAMPP, I’ll be using it on many more projects in the future.

Plugins can save the day
I’m usually not a big fan of using “cheat codes” (except for using Game Genie back in the day, they let you do some awesome stuff), but when it comes to having something that will help you get your site up and running when you have limited time to do so, they will save you a ton of time. Again, you can’t upload plugins to your wordpress site, but you can upload them when wordpress is installed on your server. I’ve actually come to embrace plugins and pre-built libraries in general. As long as you have an understanding of how the wheel was made, why reinvent it?

There are a ton of much smarter people out there that can help you out with your wordpress questions. Hell, there are people out there that specialize in building wordpress themes. When I got stuck, there were a lot of resources that helped me get through. Here are a few that might help:

Before I end, I wanted to thank for Tristan Bagwandin for helping me get started with this site and provided me with some good links and answered some of my stupid questions.

Papervision 3D Optimization Tips

I came across this article yesterday while looking for some simple papervision3D optimization help:
http://interactivehug.com/2008/04/21/john-iacoviello-papervision3d-optimization-tips/

I discovered some of them through my own trial and error process while some others helped double the overall framerate of my swf from 15/30 or so to around 28/30.

The most valuable processor saving tip that I discovered was that you should only make your viewport dimensions as large as you need it to be. Originally, my viewport was the same dimension as the stage, but when I decreased it so that it was only the size of the area that I need to be papervision3d, that’s when I saw the greatest jump is framerate efficiency.

Getting stop() to stop

In as3, the introduction to of the display list has made the stop() method a little less straightforward. Traditionally, when you used stop() on the timeline of a movieclip, it would do just that, stop the playhead from playing past where that script is. To be fare, this does still work, but only if you place the movieclip on the timeline manually (not via code).

Now to get a movieclip to stop on the first frame when added to the display list via the addChild() method, you must be sure to add stop() once it’s added. Also, note that you cannot call any other timeline based methods such as gotoAndPlay() and gotoAndStop() to a dynamically added movieclip unless it’s on the display list either.

This is specifically useful when you are using a movieclip that has a timeline based rollover and rollout animation as a button.

Adding Dynamically Named Library Items to the Display List

To add a library item to a display object using as3, here is the basic method:

var dynamicClass:Class = getDefinitionByName("libraryName") as Class;
var mcFromLibrary:MovieClip = new dynamicClass();
addChild(mcFromLibrary);

dynamicClass is a variable typed as a Class returns a reference to the class object of the class specified by the name parameter.

“libraryName” is the the name given to the MovieClip’s Class in the Symbol Properties options in the flash library.

Don’t forget to import get the definitionByName class using

import flash.utils.getDefinitionByName;

This is especially useful when looping through an array to attach multiple instances of the same movieclip. Most recently I used it to pass the reference of a loader in the library since I wanted to use the same class to potentially attach different loaders depending on what was being loaded where and when in the program.