Posts Tagged ActionScript 3

Flash’s future ain’t so bad after all

Back in February I wrote a post in which I stated that the future of Flash wasn’t so bright, well if you ask me what I think about that right now, I would say that it ain’t so bad. Why? Well, the roadmap for new features seems pretty exciting and also the array of stuff you can do with Flash is astonishing.

Molehill API (Hardware accelerated 3D)

After AdobeMax, I wanted to write a post just about this topic but I continually postponed it… but now it seems to fit perfectly with my second point so here it is. Molehill is some new low level API that enables some function calls to be hardware accelerated. Basically it permits some code to be sent to the video card instead of the processor, thus enabling us to do more crazy 3D stuff. Here is an example of what has been done with it and it is not even released yet:

If you’re a Flash Developer and this doesn’t excite you, I don’t know what will. Actually, I don’t think I looked forward so much for the next version of the player since I started using Flash. I started at FlashMX 2004, so Flash 8 gave us the filters and BitmapData; computers weren’t powerful enough to do the cool stuff with filters at the time, and I don’t know, BitmapData is pretty useful but I kinda didn’t know what I could do with it then. After that came Flash 9 with ActionScript 3, well that was nice but it took so much time for people to switch from ActionScript 2 to 3 that the excitement was kinda mitigated. Flash 10 was to follow with nothing really to offer… maybe Vectors are cool but they didn’t really impact anything. Flash 10.1? supposedly it is faster, doesn’t seem to be a game changer, the mobile stuff is cool but I wanted more for the web. Now Molehill is a very different ball game. Molehill will allow us to do way more than what we could before, both on the web and on the mobile. Gaming wise it is very easy to foresee how it will be used, but what I am mostly interested in is how it will be used for rich experiences, for rich internet applications or for data-visualization. It is the possibilities of this new technology to be used in unsuspected ways that makes it very exciting. Now, all we have to do is wait for it to come out. I bet you that the adoption rate will be very fast.

Flash everywhere

Maybe one of the good consequence of Apple saying no to Flash is everybody else saying yes to it to differentiate themselves. So yeah, Flash on a shit load of mobile ( Android, BlackBerry (PlayBook), Windows Phone 7), Flash on the TV (GoogleTV) and now Flash on the cloud (ChromeOS). It is seeing how easy it was to add a Flash app to the Google Chrome Web Store that made me realize that I was lucky to have liked Flash and have made it my job. I have so many possibilities now, from gaming to advertising (banner ads, ok I never want to do this again even if you threaten me with a gun), from website to mobile application, from your TV to the cloud. If you ever get bored as a Flash Developer there is still so many things you can do. So yeah, that did put a smile on my face and made me realize that Flash’s future wasn’t so bleak.

And to those who said that Flash would die, well it’s going to be goddamn hard to kill now on all these media… Cheers!

, , , , , , , , , , , ,

7 Comments


Event bubbling in the ActionScript world

I have been putting off writing this post but now that I am in between jobs I thought it was the good time. Well, I have been putting this off because it seemed like a good topic at the time, but eventually the concept of event bubbling became easy to me and than I felt no point in writing about it, but I guess it is not the same for every one. So here is my take on the subject.

Event bubbling in general

Event bubbling is not a concept that is particular to ActionScript but it is handled in special way by it. Event bubbling inscribe itself in an event model where events are dispatched and listened for. The bubbling part refers to event going up like bubbles in water (that’s my interpretation of the name). It doesn’t really make an sense also outside of the object oriented programming realm because of the need of encapsulation. It also implies some sort of composition because an object(Class (i’ll refer to #1 later)) needs to have another object(#2) created inside of it in order for it(#1) to listen to events dispatched by the second object(#2). Thus creating a hierarchy and enabling the possibility of event bubbling.

So in the preceding example I had 2 levels of hierarchy and every thing was fine, no need for event bubbling when object(#1) can easily listen to objects(#2) events. Now if I had 3 levels of hierarchy, object(#3) is inside of object(#2) which is inside of object(#1) we could use event bubbling to save some coding. Object(#1) can listen to object(#2) and object(#2) can listen to object(#3) but without adding code or making object(#3) public inside object(#2), object(#1) cannot receive the events from object(#3). Oh my, I hope this doesn’t sound too complicated with all those number signs. Ok so here we get to the concept, if we enabled the bubbling of events when dispatched in object(#3), the events would the go up (bubble) the hierarchy and make there way to object(#1) through object(#2) as if object(#2) had dispatched them. Keep on reading it gets easier (I hope).

Event bubbling in ActionScript

Now in the ActionScript world, event bubbling works in a particular way; it is tied to the Display List (The “Display List” is the hierarchy of graphical objects in your movie to be displayed on screen at runtime) . Meaning you cannot have event bubbling, using the event system of ActionScript, if your dispatcher is not added to the Display List (you didn’t do addChild to a children of the Stage to add your object). You can dispatch events just fine, but they won’t bubble even if you set bubbling to true.

What is cool with the Diplay List is that you can really picture the hierarchy using the mathematical structure of the tree (well if you flip it upside down it looks like a tree). Here is an visual example.

Ok, not my best drawing, but I don’t have Photoshop right now; I used Aviary for the first time and I can say it is quite nice to try, not Photoshop but I think you have to get used to it in order to see its full potential.

Now in that picture, if DisplayObject6 was to dispatch an event with bubbling to true here is who could listen to it.

  • DisplayObjectContainer5 could listen to it; it is the direct parent of DisplayObject6, no need for event bubbling here
  • DisplayObjectContainer3 could listen to it by adding a listener on DisplayObjectContainer5
  • DisplayObjectContainer1 could listen to it by adding a listener on DisplayObjectContainer3
  • The Stage (or Main class) could listen to it by adding a listener on DisplayObject1

Every body in the chain up from that object could listen to it (all at the same time if you wanted, doing each their different action upon receiving the event). If at some point you would like to stop the bubbling of the event you can always do so by using the stopPropagation method in the event class in your event handler method.

So as you see event bubbling is not a really hard concept and can save you from writing some boring repetitive code. (event handler methods). Anyway I might revisit this post later on to fix some things because I don’t think I was clear enough. Maybe I’ll had some code.

, , , , ,

3 Comments


Using the ActionScript 3 YouTube Api

On October 14th YouTube released a new version of it’s API for Flash. This version would support ActionScript 3. Previously discussed on here was the library TubeLoc which was basically an AS3 wrapper around the ActionScript 2 API. Now the new API does all TubeLoc pertmitted us to do and even more.

Well loading a YouTube video in ActionScript 3 has never been easier and there is nothing to download (which has its downside in some way)to get started.

Here is all the code needed to load a YouTube movie:

package {
 import flash.display.DisplayObject;
 import flash.display.Loader;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.net.URLRequest;
 
 public class Main extends Sprite {
  private var _loader : Loader;
  private var _player : Object;
 
  public function Main() { 
  _loader = new Loader();
  _loader.contentLoaderInfo.addEventListener(Event.INIT, _onLoaderInit, false, 0, true);
  _loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
  }
 
  private function _onLoaderInit(event : Event) : void {
  _player = _loader.content; 
  _player.addEventListener("onReady", _onPlayerReady, false, 0, true);
  addChild (DisplayObject(_player));
 
  _loader.contentLoaderInfo.removeEventListener(Event.INIT, _onLoaderInit);
  _loader = null;
  }
 
  private function _onPlayerReady(event : Event) : void {
  _player.removeEventListener("onReady", _onPlayerReady);
  // Once this event has been dispatched by the player, we can use
  // cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
  // to load a particular YouTube video.  
  _player.setSize(640, 360);
  _player.loadVideoById("D2gqThOfHu4");
  }
 }
}

You can compile this code as an ActionScript project or make it the Document class of an fla in the Flash IDE to make it work.

So you start by loading the player using a normal Loader. Once the player is loaded you have to wait for it to send the onReady event before you can interact with it. Once this is done you can call all of the function from the API.

The previous code would load the chromeless YouTube player; but if you wanted to use the controls from YouTube you would only have to replace one line:

//_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));//replace this line with the following
_loader.load(new URLRequest("http://www.youtube.com/v/VIDEO_ID?version=3"));//replace VIDEO_ID with the id of the video you want to load in the previous case :"D2gqThOfHu4"
 
//also you can comment the following line if you don't want the video to start automatically:
_player.loadVideoById("D2gqThOfHu4");

All the functionalities that where accessible with TubeLoc are also accessible with the AS3 API and there are some more. Those are methods to control the quality setting of the loaded movie. You can set the quality to small, medium, large and hd720. To do so you have 3 methods on the player. getPlaybackQuality():String will return the quality of the video currently playing. setPlaybackQuality(suggestedQuality:String) enables you to set the quality. Finally, getAvailableQualityLevels():Array will return you all the possibilities of quality that you can set the current video to.

For more information on the topic, refer to the API : http://code.google.com/apis/youtube/flash_api_reference.html

, , , , ,

14 Comments


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
    }
  }
}

, , ,

8 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

, , , , , , , ,

12 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!

, , , , ,

13 Comments


How to make Collada model double sided in Papervision3D

Well I searched for this for a little while and even tough it is pretty easy, if I didn’t figure it out at first probably other people had the same absence of mind. Also I find it hard to find example of Papervision3D and know which version was used; you find a lot of examples but you never know if the API changed since then so I am going to do a complete example with the version used.

The version used for this example is 2.1.92.

What I wanted to do was to load a Collada model in Flash an animate it. Every thing was going fine with the test models until I used the real models. You see the real models had holes in them that allowed you to see inside the model. Now if your material is single sided, when looking inside, you are going to see through the material and it will look buggy. The solution to this is just to make all material in your model (you can map multiple textures in one loaded Collada model), but that is not as easy as it sound. I tried a couple of options before hitting myself on the face. What did you learn back with ActionScript 2; wait till something is loaded before trying to modify it. This also applies to loaded models. Once loaded I made a little function that would cycle through all materials and make them double side.

Here is the code for the example :

//create all the actors of a Papervision3D scene
 
var viewport:Viewport3D = new Viewport3D(1000, 800);
addChild(viewport);
 
var renderer:BasicRenderEngine = new BasicRenderEngine();
var camera:Camera3D = new Camera3D();
var scene:Scene3D = new Scene3D();
 
//create the DAE/Collada object and load the model
 
var model:DAE = new DAE(false);
model.load("model.dae");
model.addEventListener(FileLoadEvent.LOAD_COMPLETE , daeLoadComplete, false, 0, true);
scene.addChild(model);
//finally add the enter frame listener to render the scene
 
addEventListener(Event.ENTER_FRAME, render, false, 0, true);
 
function render(event:Event):void{
  renderer.renderScene(scene, camera, viewport);
}
 
//this is where the magic happens, we cycle through all the materials of the model and make them double sided
 
function daeLoadComplete(event:FileLoadEvent):void{
  var matList:MaterialsList;
  var mat:MaterialObject3D;
  matList = model.materials;
  if ( matList ) {
    for each (mat in matList.materialsByName) {
      mat.doubleSided = true;
    }
  }
}

I didn’t include the import statement because I plainly forgot to send them to myself, but I will update this post to add them. Have fun loading models!

, , ,

6 Comments


My article on Google Analytics for Flash in FFDMag

I wrote this a couple months back for FFDMag and now that some time has passed I thought it would be a good idea to also post it on my blog and get some Google juice for the work that I put into it. So here it is:

In this time of economic crisis, marketing budgets are shifting from traditional to digital because of the later’s ability to provide data about its effects. Flash has never been great at web analytics, but a new library, Google Analytics for Flash, is going to change this. This article will focus on how to install this library, how to use it and will explain some of its key concepts.

Installation

Well the first thing to do before getting started is to install the library. This might not be as obvious as it should be so I thought it would be good to explain it here. When you download the zip file from the Google Code page for Google Analytics for Flash, what you’ll get in it is two SWC files. Now SWC files are a common thing in the Flex world, but they are not so common in the Flash world. This is where the difficulty lies.

Flash CS4

There is a new feature in Flash CS4 that enables you to import SWC libraries a bit in the way that you would do it in Flex. All you have to do is open the publish profile and click on the Flash tab. Now click on the Actionscript 3 settings; on the window that will pop-up you will see a red envelope icon, clicking on this will enable you to import the SWC file.

screenshot1

Flash CS3

Now it ain’t that easy for Flash developers still using Flash CS3 (the majority of them I guess). I have found two ways of getting the same results.

First you could use a Subversion client like TurtleSVN to checkout(download) the source code of the library. This will give you access to the Actionscript files (.as) that were used to make the SWC library. Once you have those files just copy them in your project directory and you’re ready to go.

If you don’t want to bother with svn, you can copy the SWC files in the Component directory of your Flash installation. Now this is the intended use of the SWC files by the makers, but I found it is more complicated than it should have been. If you want to do it that way copy the SWC files in the following folder in windows:

C:\Program Files\Adobe\Adobe Flash CS3\language\Configuration\Components

And the following folder if you are using a Mac:

Macintosh HD:Applications:Adobe Flash CS3:Configuration:Components

The next time you will start Flash, in your component window, you should see the Google Analytics for Flash components. Drag the component in the library and you can go on to the next step.

screenshot2

On to tracking

Tracking is the easiest part of the process and is fairly intuitive. You have to do a bit more work than you would with an HTML website, but in the end you gain more control.

All you have to do is import the library and create the tracker this way:

import com.google.analytics.AnalyticsTracker;
import com.google.analytics.GATracker;
 
var _tracker:AnalyticsTracker = new GATracker( main, "UA-7777777-7", "AS3");

The first parameter in this case refers to a DisplayObject on the stage or the stage itself. The second parameter is the id for the Google Analytics profile you want the data to be sent to. The third parameter is the mode in which the tracker will function, in this case AS3 mode. An other mode that the tracker can be set to is the Bridge mode; I’ll discuss the difference between the two modes later on.

You are now ready to track. The tracker you just created will give you access to two method of tracking: tracking pages and tracking events.

For pages, you can clearly grasp the concept when you think of an HTML website. Each time the browser will refresh or change a page and that page is from your website, a pageview is sent to Google Analytics. Now you can translate the same concept to Flash and rich internet applications, but those tends to have less pages than HTML websites. When I try to define pages in my Flash website, I try to think in sections, example: the contact section, the home section, the help section etc.

Here is the code you would write to track a pageview:

_tracker.trackPageview(yourSectionName + "/");

Events are a metric that is more suited to Flash and RIA than pageViews. Event tracking is still in beta so it is not enabled on all profiles. You can ask Google to activate events on your account by filling the form found on this page:

http://code.google.com/p/gaforflash/wiki/EventTrackingRequest.

Events are best suited to track user’s interaction with your project: how many user fully saw your video, how many clicked on the mute sound button, etc.

This is what you would write to send and event:

_tracker.trackEvent("English", "Client Satisfaction", "Question 3", value);

The trackEvent funciton can take up to 4 parameters, the last two being optional. They are in order Category, Action, Label and Value and are all Strings except the last one that has to be a non-negative integer. Google Analytics suggest some use of these parameters, but in the end, it’s up to you to decide how you want to define them. More information about Events here:

http://code.google.com/apis/analytics/docs/eventTrackerGuide.html

Bridge vs AS3

I have only talked about the AS3 mode so far because it is the one I use more often. It is mostly used when you’re entire site is made in Flash or also when your content will be embedded somewhere you don’t have access to the HTML. This is the case for widget and games that are embedded on multiple sites.

As for Bridge mode there is two cases where I would use it. First if your Flash is just a part of a bigger website done in HTML that already uses Google Analytics, then using Bridge mode will use the tracker of the html page blending in the data of the Flash content with the rest. Secondly, not all of the Google Analytics API is available using AS3 mode so if you need advanced functions or ones that are not enabled than you have no choices but to use Bridge mode. The code is a bit different from AS3 mode so I’m going to provide a sample:

var _tracker:AnalyticsTracker = new GATracker( main, "window.PageTracker", "Bridge");

The first parameter in this case still refers to a DisplayObject on the stage. The second one has to be the name of your Javascript PageTracker Object preceded by “window.” and the last one is to tell the tracker to be in Bridge mode. Since, Flash will need to communicate with the javascript while in Bridge mode, you have to be sure that allowScriptAccess is set to always in the html page that embeds the Flash content.

Visual Debug

One cool thing about GA for Flash is the Visual Debug. All you have to do to enable it is add an extra parameter when you initialize the tracker.

var _tracker:AnalyticsTracker = new GATracker( main, "UA-7777777-7", "AS3", true);

Doing this will add a layer on top of your application where all the actions the tracker performs will be listed.

screenshot3

What is neat about this is that you can now see instantly what you are tracking. With the javascript API, it is hard to see exactly what you are sending because you have to note down what you did and go check 4-5 hours later to see if tracked correctly (Google Analytics shows data after a delay of a few hours). With the Visual Debug you can see if you are sending more events than you should or if one label is misspelled etc.

Even if Google Analytics for Flash is a great library, it has some drawbacks, the biggest one being that it will add 40k to the size of your Flash content. But even with that in mind, I think it is worth using in every Flash project. Go on, get tracking!

Ressources

Google Code:

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

Developer group:

http://groups.google.com/group/ga-for-flash?pli=1

Adobe Max presentation on Google Analytics for Flash:

http://tv.adobe.com/#vi+f15385v1040

, , ,

2 Comments


Introduction to TimelineLite / TimelineMax

TimelineLite is a new library from the maker of TweenLite that enables you to group TweenLite instances (Tweens) to create the equivalent of the Flash Authoring Tool Timeline but in code. If you don’t know what TweenLite is head over to my tutorial on it first.

What is it for

The goal of this library is to give more power to the already powerful TweenLite library and to emulate some of the MovieClip’s functionalities. Once built, a TimelineLite instance will possess some methods that we’ve known for a long time: play(), stop(), gotoAndPlay(), etc. Three methods are used to create the timeline: append(), insert(), insertMultipple(). I prefer the insert method, it gives you more flexibility because you can set the time at which the Tween starts. The append() method will simply add your TweenLite instance at the end of the current timeline.

Here are some examples of how you would create a TimelineLite :

var myTimeline:TimelineLite = new TimelineLite();
 
//this will have 3 tween starting one after the one before is done
myTimeline.append(new TweenLite(mc, 1, {x:200, y:100}));
myTimeline.append(new TweenLite(mc, 0.5, {alpha:0}));
myTimeline.append(new TweenLite(mc, 0.5, {alpha:1}));
 
myTimeline.play();
 
//this one will have concurrent tweens a bit like layered tweens in the Flash Timeline
myTimeline.insert(new TweenLite(mc, 1, {x:200, y:100}), 0);
myTimeline.insert(new TweenLite(mc, 0.5, {alpha:0}), 0.75);
myTimeline.insert(new TweenLite(mc, 0.5, {scaleX:2}), 1.25);

Some of the cool stuff you can do with is that inside a TimelineLite you can insert other TimelineLite instances. Also you can add Labels and tween using TweenLite to those labels. You can tween the time of the timeline as well as the progress. Here are examples of what I just mentioned:

var myTimeline:TimelineLite = new TimelineLite();
myTimeline.insert(new TweenLite(mc, 1, {x:200, y:100}), 0);
myTimeline.insert(new TweenLite(mc, 0.5, {alpha:0}), 0.75);
myTimeline.insert(new TweenLite(mc, 0.5, {scaleX:2}), 1);
 
//Tween the timeline to any place in percent (from 0 to 1)
TweenLite.to(myTimeline, 0.5, {progress:1});
 
//Tween to a particular second in time (from 0 to the duration of the timeline)
TweenLite.to(myTimeline, 0.5, {time:0.75});

Its advantages

The major advantage that TimelineLite posesses over real timeline is the fact that it is dynamic. Meaning that you could make an function that takes a display object, that function would create an animation based on it and return a TimelineLite instance that you could use afterward. Then you could use that function to create the same animation on multiple display objects. Another example is that you could create animation based on what the user does, like you make him choose a number and you append that many instances on TweenLite in your TimelineLite (easy to do with traditionnal timeline too, but its just an example).

Its Max conterpart

As for the TweenLite library, TimelineLite has its Max equivalent, TimelineMax, which has more features like AS3 event listeners, repeat, repeatDelay, yoyo, addCallback(), removeCallback(), getActive(), etc.  Just to tell you how good this library is,  I have done a TimelineLite instance that tweened 25 display objects and 625 TweenLite instances and it worked perfectly fine, it wasn’t even slowing down.

, , , , , ,

4 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.

, , , , , ,

12 Comments