Archive for category ActionScript 3

More on preloaders: passing the loaderInfo

I previously made 2 posts on the topic of preloaders (The right way to do a preloader in AS3, External Preloader; more complex cases), well this post will be a continuation of those. And one that I believe not everyone will agree with me. I know that because I didn’t agree with it at first but the more I thought about it the more it felt right.

When it comes to code I’m a bit of a fascist, I have trouble accepting habits of other coders if they are not the same as mine. So when I see something different my first reaction is to frown upon it (I am talking just about code; I am a very open minded person). When I first saw this mean of passing variables from the preloader to the main application that a coworker was doing I didn’t quite like it.

In the post about the more complex preloaders, I showed how to use an interface to pass data from the preloader to the loaded (main) movie. Now this part of the code is still the same. What changes is that instead of passing the flashVars (variables that are passed to the flash from the html embed code or javascript) individually inside fo the init method of the Main class (also in the interface), we pass them all together by giving the root.loaderInfo instead.

I already know what you are going to say: this is not strictly typed so it is bad. I know, I know, but if you think about it a bit you see that at some point the flashVars are not typed anyway; when they transition from html to flash. So what is the harm of perpetuating this just one level more? In the init method inside the Main class, the first thing I do is that I type the parameters passed, so I do end up typing my variables.

Now, you’re going to ask what do you gain from this? Well, since the preloader is an external file, every time you are going to pass more variables to the Flash from the HTML, you will have to modify 3 files : the preloader.fla, the IMain.as and the Main.as. Now if you pass the loaderInfo instead of the individual flashVars, you will only need to modify the Main.as since it is there that you type the variables. You completely bypass the preloader, which in a way make sense since your preloader doesn’t need to know about your application, all it does is to load it. once your preloader is completed you don’t ever have to touch it again.

Here is some code to illustrate this. In the preloader :

var mainContent:IMain;
function onLoadComplete(event:Event):void{ // this would be the function that the loader would call when the loading is completed
  mainContent = IMain(loader.content);
  addChild(Sprite(mainContent) );
  mainContent.init( root.loaderInfo);
}

And in the Main class :

package{
  import com.zedia.interfaces.IMain;
  import com.display.Sprite;
  import com.display.LoaderInfo;
 
  public class Main extends Sprite implements IMain{
    public function init(loaderInfo:LoaderInfo):void{      
      var flashVar1:String = String(loaderInfo.parameters.flashVar1);
      var flashVar2:Number = Number(loaderInfo.parameters.flashVar2);
      //do something with the FlashVars
    }
  }
}

, , ,

2 Comments


Fonts are my bane; not anymore!

I hate managing fonts in Flash, I truly hate it. I don’t understand why it is not easier than this after all that time. How about underline; why can’t we still underline in the Flash IDE? That shouldn’t be voodoo magic, even Notepad has underline, ok, Notepad doesn’t have the underlining functionality, but Wordpad does.

Anyway, my biggest problem with fonts and Flash is not the underlining problem, but when you start using static and dynamic textfields with the same font family but with different font style. When you do that, your dynamic textfields will just not show and that is really annoying. A solution that works is if you put all textfields dynamic, but that’s even more annoying.

Now a really cool feature is that you can now embed fonts using the embed tag just like this:

[Embed(source="assets/fonts/GNL_____.PFB", fontName ="zedia GillSansLight", unicodeRange='U+0020-U+007A, U+00C0-U+00F6, U+2019', mimeType="application/x-font-truetype")]
private var GillSansLight2:Class;

Not sure that this will work when you compile using the Flash IDE, but when doing ActionScript projects or Flex projects this works just fine. This way you can embed ttf, otf and pfb fonts. I am not quite sure how to embed fonts on a Mac system, it will still work with those formats, but I know Macintosh has other formats. The thing that makes this work is that you can specify the font name. Be sure to specify a name that you know Flash wouldn’t specify. My coworker gave me the trick to add the name of the project in the font name that way it’s always going to be different than Flash. If you don’t make it different you will still run in the problem of your dynamic textfields not showing up.

Once you have embedded the font you need to register it in your application like this:

Font.registerFont(GillSansLight2);

This will make the font available anywhere in your application. All you need to do is create a TextFormat with that font and assign that TextFormat to your textfield:

var tf:TextFormat = new TextFormat("zedia GillSansLight");//this is what you put into fontName in the embed tag
myTextfield.embedFonts = true; //this line is also important
myTextfield.defaultTextFormat = tf; //always assign the default textformat before modifying the text property
myTextfiled.text = "lorem ipsum";

Now, using this technique you can choose exactly what character from the font you want to embed. In the previous example the unicodeRange represented those characters:

U+0020-U+007A = SPACE!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz
U+00C0-U+00F6 = ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö
U+2019 = ’

This is a pretty safe set, but you can always change it and optimize it.

Here is a good resource to do Unicode conversion:
http://rishida.net/scripts/uniview/conversion.php

, , , , , , , ,

8 Comments


How to load a YouTube movie into Flash using TubeLoc

I have written this article a while back for FFDMag, but I thought I would put it here also. It lost a bit of relevance because YouTube now has an AS3 API for its player, but if you work on a project that uses TubeLoc, I think this article can be useful.

What you should know:
- Basic knowledge of ActionScript
- Basic knowledge of YouTube

What you will learn:
- How to load YouTube videos into Flash
- How to use the TubeLoc library to control those videos

Embedding a YouTube movie in an HTML page is an easy task, but we can’t say the same about embedding a YouTube clip in a Flash/Flex website. TubeLoc, an opensource library, is there to make that easier.

Before TubeLoc, you could always go and try to find the address of the FLV the YouTube player is loading and load that FLV directly into your Flash application, but YouTube changes the address almost every night, so it wasn’t a very long term solution. Another problem that TubeLoc solves is the fact that the YouTube player is made in ActionScript 2 and most projects now are using ActionScript 3, so it was hard interfacing with the player. TubeLoc is a wrapper around the the AS2 player and show us an AS3 API, but behind the scene it handles the YouTube player using local connection.

To get started with TubeLoc you will first need to download the library at this address:

http://code.google.com/p/tubeloc/

There you will also find a great demo showing you what you can do with the library. You can pause, stop, play, mute, seek, change the volume, change the the size of the video and even load the video without the YouTube player chrome (so you won’t see the play button from YouTube the only thing that will be there is the YouTube logo at the bottom right of the video).

In the zip file that you download from the previous url, copy the “com” folder located in the “as3/src” folder in the same directory where your FLA will be. Also copy there the file as2_tubeloc.swf from the folder “as3/lib”. Now we can get coding. Here is all that is needed to load a YouTube movie into Flash:

import com.enefekt.tubeloc.MovieSprite;
import com.enefekt.tubeloc.event.*;
 
var youtubeMovie:MovieSprite = new MovieSprite(null, true);
youtubeMovie.addEventListener(PlayerReadyEvent.PLAYER_READY, onPlayerReady);
addChild(youtubeMovie);
 
function onPlayerReady(event_p:PlayerReadyEvent):void {
//it's just cleaner to remove listener that won't be used again
youtubeMovie.removeEventListener(PlayerReadyEvent.PLAYER_READY, onPlayerReady);
 
//you can set the size of the movie this way
youtubeMovie.width = 370;
youtubeMovie.height = 276;
 
youtubeMovie.loadVideoById("tprMEs-zfQA");
}

The first lines import the library from the “com” folder we copied. After that it creates the MovieSprite. The first parameter is the id of the YouTube movie, since I will set that later I can just pass null to it. The second parameter is if I want to use the chromeless player, in this case I set it to true. The chromeless player is usefull when you want the video player to have control that are similar to the rest of your application. It is also usefull when you want to put your video under a mask to escape the traditonnal square look of videos. If we continue with the code, after we created the MovieSprite, we have to wait for the player to be initialized to go on that’s why we put an event listener on the MovieSprite(youtubeMovie). Once the listener function is called, all that is left to do is call the loadVideoById method. Finding a video id from YouTube is really easy; if the url of the video you want to load looks like this:

http://www.youtube.com/watch?v=tprMEs-zfQA

Than your id is only the last part : “tprMEs-zfQA”.

Now if you want to control your video all you have to do is :

//this will pause the video
youtubeMovie.pauseVideo()
 
//this will make it play again
youtubeMovie.playVideo()
 
//to mute the video
youtubeMovie.mute()
 
//to set the volume to half of maximum
youtubeMovie.setVolume(50)
 
//to seek in the video to 20 seconds
youtubeMovie.seekTo(20)

Well that is all it take to load a YouTube movie into Flash. I should warn you of some pitfalls; by reading the issues on the google code page, there seems to be problems with loading multiple videos at the same time. Also, destroying an instance of a MovieSprite seems to inhibit you from creating another one after so you should always keep an instance of you MovieSprite alive. Aside from that TubeLoc is an awesome library and I hope to see the proliferation of YouTube videos inside of Flash!

, , , , ,

8 Comments


How to connect to Google Analytics Data API in Flash

In one of my previous post, I explained how to connect to Google Analytics Data API in AIR. The problem with that way of connecting was that it only worked in AIR. In Flash it works locally, but as soon as you put in on your web server it stops working. Not it is cool to build an AIR (desktop) application that pulls data from Google Analytics, but it would also be cool to build a web application that does the same thing. Well I found out how to do just that. It is a bit more complicated because it involves a bit of server side coding, in this case PHP.

How the process works is that first you login to Google Analytics, Google will then send you a token that you must use when asking for data. So we will have two simple PHP files; one to login in and one to ask for data.

The first one looks like this:

<?php
//this file is called get_token.php
$user = $_REQUEST[user];
$pass = $_REQUEST[pass]
 
require_once 'curl.php';
$curl = new Curl;
$response = $curl-&gt;post('https://www.google.com/accounts/ClientLogin', array(accountType => "GOOGLE",  Email =>$user, Passwd => $pass, service => "analytics", source => "zedia-GAStats-0" ));
$tempArray = explode("Auth=", $response);
?>
<root>
	<token><?php echo ($tempArray[1] ); ?></token>
</root>

The second one looks like this:

<?php
//this file is called call_ga.php
require_once 'curl.php';
$url = $_REQUEST["url"];
$token = $_REQUEST["token"];
 
$curl2 = curl_init();
curl_setopt($curl2, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl2, CURLOPT_HEADER, "0");
curl_setopt($curl2, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl2, CURLOPT_URL, $url);
 
curl_setopt($curl2, CURLOPT_HTTPHEADER, array('Authorization: GoogleLogin auth=' . $token));
$response2 = curl_exec($curl2);
echo ($response2);
?>

As you can see to make my calls to Google I am using the cURL library that is usually already installed on your server if you have PHP. Also for the get_token.php I am also using the Curl class, made by Sean Huber, that just makes it easier to work with cURL.  Upload these files to your server. Now that we have the server side figured out, we can move on to the Flash part;  here it is:

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.text.TextField;
 
public class Main extends Sprite
{
  private var loader:URLLoader;
  private var _loader2:URLLoader;
  private var _textField:TextField;
  private var _token:String;
  private var _buffer:String = "";
  public function Main():void
  {
    loader = new URLLoader();
    loader.addEventListener(Event.COMPLETE, _onTokenLoaded, false, 0, true);
   //this call will load the token
 
    loader.load(new URLRequest("http://www.YOUR_URL_WHERE_THE_PHP_RESIDE.net/get_token.php?user=YOUR_USERNAME&pass=YOUR_PASSWORD"));
 
    _textField = new TextField();
    _textField.height = 300;
    _textField.width = 300;
    _textField.multiline = true;
    _textField.wordWrap = true;
 
    addChild(_textField);
  }
 
  private function _onTokenLoaded(event:Event):void {
    var tempString:String = String(loader.data);
    tempString = tempString.substring(1, tempString.length);
    var tempXML:XML = XML(tempString);
    _token = tempXML.token;
 
    _textField.text = _token;
 
    _loader2 = new URLLoader();
    _loader2.addEventListener(Event.COMPLETE, _onFeedLoaded, false, 0, true);
 
    var request:URLRequest = new URLRequest("http://www.YOUR_URL_WHERE_THE_PHP_RESIDE.net/call_ga.php");
    var urlVar:URLVariables = new URLVariables();
    urlVar.token = _token;
    urlVar.url = "https://www.google.com/analytics/feeds/accounts/default";
    request.data = urlVar;
 
    _loader2.load(request);
  }
 
  private function _onFeedLoaded(event:Event):void {
    _textField.text = String (_loader2.data);
  }
 }
}

What you basically do is that you use your server to do all the communication between the Flash and Google. Everytime you will want a different feed to get different data you will call the call_ga.php file. It is that simple. If you have any question on this feel free to ask them in the comments.

, , , , , ,

11 Comments


as3Crypto and php, what a fun ride!

Actually not so fun, but I did manage (I should say we because I wasn’t alone in this). Cryptography is not my thing, eh, not everything can be your thing so I accept it. There is just too much to learn: hash functions, public keys, symmetric ciphers, etc. Want we wanted to do was to encrypt data on the As3 side and decrypt it on the php side. I was aware that there was some cryptographic algorythms in the as3corelib, but none of them (MD5, SHA-1) fitted our needs. There is another great cryptography library out there and it is as3Crypto; the problem is that it is a bit hard to get around, there is a lot to choose from. We settled on AES (Advanced Encryption Standard). After 2 hours of trying to get it to work, we found this great post on Google groups (about middle of the page). I am copying the content here to make it easier for people to find. I have to give all the credit for this post to Jason Foglia who posted his code.

Here is the As3 Class:

 
package
{
        import flash.display.Sprite;
        import flash.utils.ByteArray;
 
        import com.hurlant.crypto.symmetric.ICipher;
        import com.hurlant.crypto.symmetric.IVMode;
        import com.hurlant.crypto.symmetric.IMode;
        import com.hurlant.crypto.symmetric.NullPad;
        import com.hurlant.crypto.symmetric.PKCS5;
        import com.hurlant.crypto.symmetric.IPad;
        import com.hurlant.util.Base64;
        import com.hurlant.util.Hex;
        import com.hurlant.crypto.Crypto;
 
        public class CryptoCode extends Sprite
        {
                private var type:String='simple-des-ecb';
                private var key:ByteArray;
 
                public function CryptoCode()
                {
                        init();
                }
 
                private function init():void
                {
                        key = Hex.toArray(Hex.fromString('TESTTEST'));// can only be 8 characters long
 
                        trace(encrypt('TEST TEST'));
                        trace(decrypt(encrypt('TEST TEST'));
                }
 
                private function encrypt(txt:String = ''):String
                {
                        var data:ByteArray = Hex.toArray(Hex.fromString(txt));
 
                        var pad:IPad = new PKCS5;
                        var mode:ICipher = Crypto.getCipher(type, key, pad);
                        pad.setBlockSize(mode.getBlockSize());
                        mode.encrypt(data);
                        return Base64.encodeByteArray(data);
                }
                private function decrypt(txt:String = ''):String
                {
                        var data:ByteArray = Base64.decodeToByteArray(txt);
                        var pad:IPad = new PKCS5;
                        var mode:ICipher = Crypto.getCipher(type, key, pad);
                        pad.setBlockSize(mode.getBlockSize());
                        mode.decrypt(data);
                        return Hex.toString(Hex.fromArray(data));
                }
        }
 
}

Here is the php class:

 
<?
class Crypt
{
        var $key = NULL;
        var $iv = NULL;
        var $iv_size = NULL;
 
        function Crypt()
        {
                $this->init();
        }
 
        function init($key = "")
        {
                $this->key = ($key != "") ? $key : "";
 
                $this->algorithm = MCRYPT_DES;
                $this->mode = MCRYPT_MODE_ECB;
 
                $this->iv_size = mcrypt_get_iv_size($this->algorithm, $this->mode);
                $this->iv = mcrypt_create_iv($this->iv_size, MCRYPT_RAND);
        }
 
        function encrypt($data)
        {
                $size = mcrypt_get_block_size($this->algorithm, $this->mode);
                $data = $this->pkcs5_pad($data, $size);
                return base64_encode(mcrypt_encrypt($this->algorithm, $this->key, $data, $this->mode, $this->iv));
        }
 
        function decrypt($data)
        {
                return $this->pkcs5_unpad(rtrim(mcrypt_decrypt($this->algorithm, $this->key, base64_decode($data), $this->mode, $this->iv)));
        }
 
        function pkcs5_pad($text, $blocksize)
        {
                $pad = $blocksize - (strlen($text) % $blocksize);
                return $text . str_repeat(chr($pad), $pad);
        }
 
        function pkcs5_unpad($text)
        {
                $pad = ord($text{strlen($text)-1});
                if ($pad > strlen($text)) return false;
                if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
                return substr($text, 0, -1 * $pad);
        }
}
 
?>

Now if you use the encrypt method of one you can send the data to the other one and decrypt it in the other language if you use the same key. Works like a charm. There is a mention that the key can only be 8 characters long but I haven’t tested it out.

, , , , , , , , ,

11 Comments


Tracing or tracking a uint as a Hex String in AS3

I feel guilty that I haven’t written in a two weeks but I have been working on a longer article and it seems that I am limited on the number of words I can write in a week. Anyway I wanted to make a small post about this topic because I had a bit of trouble to find how to do it. When you work with colours, the common way to write a colour is to write it a has hex string to a uint; example: 0xff0000. When you trace that uint what you will get is the base 10 equivalent which is not really readable and gives no hint about what colour it is. So to solve this problem here is a quick way to convert a uint into a Hexadecimal String for tracing or tracking purpose:

 
var myUint:uint = 0xff000; // this is the colour red
 
trace (myUint.toString(16)); //will trace ff0000;

My guess is that it will trace the number using 16 as a base.

Well that’s it for now might have more on AIR later on.

, , , , ,

4 Comments


How to reuse event functions

This is just a quick tip I picked up while working with a teamate.

I often came across the case that I would have to make a function exactly the same as the function that was called from an event listener because the function called from the listener would have an event as argument but the same function that I wanted to call but not from an event didn’t.

I had found multiple ways around that problem; I would make another function that both previous function would call or I would create only the listener function and when I wanted to call it from elswhere I would pass it an empty event that I would create just for it. Both these solution appeared unelegant to me.

That’s when I saw this in my teamate code:

// let say your listener is this
myButton.addEventListener(Event.COMPLETE, _activateElement, false, 0, true);
 
//your function looks like this
private function _activateElement(event:Event = null):void{
  //do something that doesn't require the event
}
 
//so from anywhere you can just call the same function like this
_activateElement();

By simply giving a default value of null to the argument, you can now reuse this function both in the context of an event listener and anywhere else.

, ,

5 Comments


Gingerbread house builder – TELUS holiday 2008 card

Just a quick post, while it is still the time, to bring you to the Gingerbread house builder we did for TELUS. I think it is a pretty little piece of flash that is fun and will make you smile. As it is the costum with holiday cards, the deadline was really tight but I think we managed well. This small rich internet application is packed with features that if you don’t stop to look, you won’t notice.

First the send to friend option actually sends a picture of the gingerbread house you built which was very nice to program. I had to take a screenshot(bitmapData.draw) of the House MovieClip encode it in JPEG (using as3corelib) and send it to the server. Next nifty detail is the print version of the recipe which also includes a picture of your creation. It wasn’t something really complicated to do considering I mostly used the send to friend code and put it in a PrintJob. Lastly, to save the recipe to PDF, instead of simply doing a navigateToURL to the PDF location, which would have opened a new tab in the browser with the PDF in it, I used FileReference.download to pop the download window so that the file is directly downloaded.

Independently these attentions might not seem like much, but if you put it all together the user won’t notice it but he will still feel this is a better application, without knowing why. Don’t get me wrong, I’m am not saying that the TELUS holiday card is the best application out there; I am saying that paying attention to details is what makes the difference between a nice application and a great one.

In that sense, I think there are stuff we could have done better. Mostly sound wise, to emphasize the meerkat (that is the name of the current TELUS critter) sneaking to take a bite on your gingerbread house. I’m not good at all in audio and when it comes to it I need help, and sound is somewhat not needed to make a website / application functionnal and beautiful, so it is often forgotten. But I will make sure in following projects to give it the proper time.

As I always do here is a list of the libraries I used to build it:

Well that’s it, enjoy your holidays, I surely will!

, , , , , ,

2 Comments


Sending byteArray and variables to server-side script at the same time

While using the URLLoader classyou can send two types of data to the server. You can either send variables through the URLVariables or by giving a ByteArray to the data property of the URLRequest class. Here is how you would send variables:

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLVariables;
 
  public class URLVariablesExample extends Sprite {
    public function URLVariablesExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php";
      var request:URLRequest = new URLRequest(url);
      var variables:URLVariables = new URLVariables();
 
      variables.exampleSessionId = new Date().getTime();
      variables.exampleUserLabel = "guest";
 
      request.data = variables;
 
      var loader:URLLoader = new URLLoader();
      loader.load(request)
    }
  }
}

If you wanted to send a ByteArray, let say to save an image made in your flash on the server, here is how you would pass the data (I’m using the coreLib to convert bitmapData to JPG format which will return a ByteArray) :

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestMethod;
  import flash.display.BitmapData;
  import flash.utils.ByteArray;
  import com.adobe.images.JPGEncoder;
 
  public class ByteArraySendExample extends Sprite {
    public function  ByteArraySendExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php";
      var someBitmapData:BitmapData = new BitmapData();//let say we have some bitmapdata
 
      //using the jpeg encoder from the core library
      var jpgEncoder:JPGEncoder = new JPGEncoder(80);
      var myByteArray:ByteArray = jpgEncoder.encode(someBitmapData);
 
      var request:URLRequest = new URLRequest(url);
      request.method = URLRequestMethod.POST;
 
      request.data = myByteArray;
      var loader:URLLoader = new URLLoader();
 
      loader.load(request)
   }
  }
}

The thing is, there is no actual documentation when you want to send both a byteArray and variables. As you can see in the examples, when you send variables, you set the data property of the URLRequest equal the your URLVariables, but when you send a byteArray you also set the data property equal to your byteArray. So you cannot send both type of data at the same time this way. The way I found is actually pretty simple and I don’t why others have not blogged about this (trust me I have looked for this). What you do is you set the data of the URLRequest equal to the byteArray, but you put your variables in the url String of the URLRequest. Here is some code showing it:

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestMethod;
  import flash.display.BitmapData;
  import flash.utils.ByteArray;
  import com.adobe.images.JPGEncoder;
 
  public class   ByteArrayAndVariableSendExample extends Sprite {
    public function  ByteArrayAndVariableSendExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php?exampleSessionId="new Date().getTime() + "&amp;exampleUserLabel=guest" ;
 
      var someBitmapData:BitmapData = new BitmapData();//let say we have some bitmapdata
 
      //using the jpeg encoder from the core library
      var jpgEncoder:JPGEncoder = new JPGEncoder(80);
      var myByteArray:ByteArray = jpgEncoder.encode(someBitmapData);
 
      var request:URLRequest = new URLRequest(url);
      request.method = URLRequestMethod.POST;
 
      request.data = myByteArray;
      var loader:URLLoader = new URLLoader();
 
      loader.load(request)
    }
  }
}

Then in your server-side script you recover the variables in the query string and the byteArray in the post part. It’s that simple.

, , , , , , ,

10 Comments


A bug nearly got me today

I spent most of today fighting this incredible bug and it nearly got me. At some point I even admitted defeat, which I never usually do. But while trying to circumvent the said bug, I found its Achilles’ heel and nailed it. It tried to bring me with it to the other side by grabbing my sanity, but I stood strong and in the end I thrived.

Seriously I was stuck all day on this problem that I couldn’t solve and it was a pretty one. I searched the web to find answers but sometimes your problem is so tricky that you don’t know how to describe it. Well describing it is already a good step into solving a problem, because you know what the problem is. Mine was that, I was handing over some SWF files to some third party and the file on their part wasn’t behaving the same way than on our side.

At first, I was thinking the problem came from their side as it was working properly on ours but I was wrong. After I thought it was a question of cache; browser and server, but that wasn’t right too. No it was way trickier than this.

I had 2 SWF files one loading the other. What I didn’t know was that they both compiled some ActionScript classes even if one of them definitely didn’t need them ( I didn’t created that thing). So in the application their was a duplication definition for those classes and the Flash player was just using one of the definition, the loader one not the loaded. The modification I needed to do was only on the loaded and I didn’t need to compile the loader so once the loaded file was inside the loader I couldn’t see the changes that was done in the duplicated classes. I really was pulling my hairs and all I needed to do was to compile the loader file.

I think that’s where experience kicks in; I sure will know when some changes don’t appear in a loaded file to look for duplicate definition of classes. Oh well I came out stronger. I don’t know if this post will help anyone but it sure got today’s frustration out of my chest.

,

2 Comments