#tweetcoding

If you didn’t know, Grant Skinner has introduced an interesting competition called tweetcoding!

Mixing as3 with the 140 character limit of tweeting he calls for the community to tweet visually interesting source code.

I’ve played a bit with it and tweeted my first #tweetcoding entry! See more tweetcoding here

[cc lang=”actionscript”]
g.clear(),o[++i]={x:mouseX,y:mouseY,c:r()*0xFFFFFF};for each(k in o)k.c*=.9,g.beginFill(k.c),ls(i,k.c),g.drawCircle(k.x,k.y,1),g.endFill();
[/cc]

Want to see my entry? Here it is!

tweetcode_circlecube_a png

Random Movement | Brownian revisited for as3

I have had feedback that certain random movements I program are a bit “jumpy”. Such as my old brownian movement tutorial and I really noticed it in my last tutorial, the parallax 3d depth effect tutorial. I’ve been thinking about it and looking around at some code and now have this updated brownian movement example! Updated for as3 as well as making it less jumpy.

as3brownian thumb pngFirst I’ll explain what I’ve found to be the reason of the jumpiness. And then explain and show what can be done to make this movement be more smooth.

So to examine the old jumpy code. Jump back to the first version post here. I think my technique was well thought out here, but the application was poor. It was recalculating the velocities every single frame and then incrementing the coordinate positions by the newly calculated velocities… This is where the jumpiness comes in. Even though the random value was named velocity, it didn’t actually affect the dot’s velocity, it was just a variable that stored the random value used to move the current x/y coordinates.
To help the animation be more smooth, the velocity needs to be more smooth. The velocity, rather than calculating it fresh each frame, should be randomly modified each frame. And then the new velocity will calculate the new ‘random’ position. Another addition is to introduce another force to dampen the velocity over time, so things don’t get too crazy…

Steps:

  1. Modify velocity randomly
  2. With velocity and current position, calculate a new position
  3. Dampen the velocity

Example:

Here I have a velocity for the x coordinate as well as the y. I’m also experimenting with a z velocity. This adjusts the alpha and scale for depth perception. It doesn’t actually edit the depth or layer the dot shows up on the stage however… keyword here: experimenting. 🙂
[kml_flashembed fversion=”8.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/02/as3random_brownian_movement.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”550″ wmode=”transparent”]

Get Adobe Flash player

[/kml_flashembed]

Actionscript:

[cc lang=”actionscript”]
//number of balls
var numBalls:uint = 50;
var defaultBallSize:uint = 30;

//init
makeDots();

function makeDots():void {
//create desired number of balls
for (var ballNum:uint=0; ballNum stage.stageWidth) {
thisBall.x = 0 – thisBall.width;
}
else if(thisBall.x < 0 - thisBall.width) { thisBall.x = stage.stageWidth; } if(thisBall.y > stage.stageHeight) {
thisBall.y = 0 – thisBall.height;
}
else if(thisBall.y < 0 - thisBall.height) { thisBall.y = stage.stageHeight; }if (thisBall.scaleX > maxScale){
thisBall.scaleX = thisBall.scaleY = maxScale;
}
else if (thisBall.scaleX < minScale){ thisBall.scaleX = thisBall.scaleY = minScale; } if (thisBall.alpha > maxAlpha){
thisBall.alpha = maxAlpha;
}
else if (thisBall.alpha < minAlpha){ thisBall.alpha = minAlpha; } }function randomColor():Number{ return Math.floor(Math.random() * 16777215); } [/cc]

Source:

as3random_brownian_movement.fla

Dynamic 3d space | Floating Sketches Tutorial

parallax_thumbI’ve had quite a few questions about how to make depth in flash. Earlier (like, 2 years ago) I put up an experiment file to give some interactive depth to some sketchbook sketches, see Floating Sketches. I’ve finally gotten around to translating that into as3. It’s still the same basic idea, Create layers of levels, and have each one respond to the mouse a little differently. The ‘closer’ depths will move faster while the farther away depths will be slower. A simple technique called Parallax.

  1. Seperate the scene into layers
  2. Place the layers in the correct depth
  3. Make closer layers react fast and farther layers slower

Example

[kml_flashembed fversion=”8.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/01/depth.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”550″]

Get Adobe Flash player

parallax_thumb
[/kml_flashembed]

Actionscript

[cc lang=”actionscript”]
//define number of layer.
var numLayers:uint = 15;
//number of items in a layer
var numBallsPerLayer:uint = 100;
var defaultBallSize:uint = 25;

var stageWidth3d:uint = 800;
var stageHeight3d:uint = 800;

var layers:Array = new Array();
//init
makeMatrix();
//3d created by layers and placing objects on each layer – the layer has it’s own distance, simulated by movement and alpha

function makeMatrix():void {
//walk through desired number of layers
for (var layerNum:uint=0; layerNumSource

depth.fla

How to as3 resize a movieClip and constrain proportions | Actionscript Tutorial

constrain proportions jpgI’ve had that exact task numerous time while scripting actionscript. I have a source image loaded externally or a mc within the program and I need to fit it into a certain area (width x height) but keep the aspect ratio the same or as photoshop calls it “constrain proportions”. I’ve done this with fancy and not so fancy formulas and equations, but finally I had it and created a simple function that would do it every time. Figured it was worth sharing cause if I’ve googled it before then others most likely will too!

This is more than just setting the width and height of an object, because that way the image is easily skewed and the natural proportions are messed up. If you want to just use scale you need to know the dimensions of the image being resized, and that’s just not scalable (no pun intended).

What we have to do is to do both. Assign the width and height to skew it, and then scale it to correct the proportion. So if we want to resize an image when we don’t know it’s current size to fit into a 300 pixel square we set the width and height of that image to 300 and then a bit of logic that can be summed up in one line:
mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
That says if the x scale is larger than the y scale set the x to the y scale amount, and vice versa. It's basically setting both scales to the smaller of the two. This works because we don't know the original size of the image, but actionscript does. scaleX and scaleY are ratios of the current width and height to the originals. A little complicated I know, but that's why I've made the function below. I know how to use it and now I don't have to think about skewing and then scaling back to keep my aspect ratio or proportion. You should see how to use it just by looking at it:
resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true)
Pass in the movieClip you want to resize, and the size you want it to fit into. So with the same example above, just do
resizeMe(image, 300);

Example

Here's an interactive example to show what I mean. It loads an external image and you click and drag the mouse around to resize it. To toggle whether you want to constrain proportions use the space bar. Type a url to any image you want to test it with and press load, or hit 'enter'.
[kml_flashembed fversion="9.0.0" movie="https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/01/constrainproportions.swf" publishmethod="dynamic" width="550" height="550"]

Get Adobe Flash player

[/kml_flashembed]

Here's a screenshot of me playing with a photo in here NOT constraining proportions.
constrain proportions jpg

Source (AS3)

The resizing function
[cc lang="actionscript"]
//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{
maxH = maxH == 0 ? maxW : maxH;
mc.width = maxW;
mc.height = maxH;
if (constrainProportions) {
mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY; } } [/cc]The full source [cc lang="actionscript"] var defaultUrl:String = "https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/11/circlecubelogo4.png"; var image:MovieClip = new MovieClip(); loadImage(); function loadImage(url:String=""):void { if (url == "" || url == defaultToLoadString) url = defaultUrl; //clear image image.visible = false; image = new MovieClip(); //add image var ldr:Loader = new Loader(); var urlReq:URLRequest = new URLRequest(url); trace("loading image: " + url); ldr.load(urlReq); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, imageCompleteHandler); image.addChild(ldr); addChild(image); }function imageCompleteHandler(e:Event):void { resizeMe(image, stage.stageWidth) }//The resizing function // parameters // required: mc = the movieClip to resize // required: maxW = either the size of the box to resize to, or just the maximum desired width // optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once) // optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true. function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{ maxH = maxH == 0 ? maxW : maxH; mc.width = maxW; mc.height = maxH; if (constrainProportions) { mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY; } }var constrainOn:Boolean = true; var isPressed:Boolean = false;stage.addEventListener(MouseEvent.MOUSE_MOVE, moved); stage.addEventListener(MouseEvent.MOUSE_DOWN, pressed); stage.addEventListener(MouseEvent.MOUSE_UP, released); stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener);function keyDownListener(e:KeyboardEvent) { if (e.keyCode == 32){//spacebar toggled(e); } if(e.keyCode == 13){//enter loadImagePress(e); } }function moved(e:Event):void{ if (isPressed) resizeMe(image, mouseX, mouseY, constrainOn); } function pressed(e:MouseEvent):void{ isPressed = true; moved(e); } function released(e:MouseEvent):void{ isPressed = false; } function toggled(e:Event):void{ constrainOn = !constrainOn; moved(e); } var defaultToLoadString:String = "type url of image to load"; toLoad.text = defaultToLoadString; toLoad.addEventListener(FocusEvent.FOCUS_IN, toLoadFocus); toLoad.addEventListener(FocusEvent.FOCUS_OUT, toLoadBlur); function toLoadFocus(e:FocusEvent):void{ if (toLoad.text == defaultToLoadString) toLoad.text = ""; } function toLoadBlur(e:FocusEvent):void{ if (toLoad.text == "") toLoad.text = defaultToLoadString; } loadBtn.addEventListener(MouseEvent.CLICK, loadImagePress); function loadImagePress(e:Event):void{ loadImage(toLoad.text); } [/cc]

Download

constrainProportions.fla

And as usual, let me know if you've got any comments questions or suggestions! Thanks,

Detect Flash Player Version | Actionscript based detection method (as3)

See my previous post about how to do this with as2: Detect Flash Player Version | Actionscript based detection method (as2)

Overview

Recently I had a requirement that I had to detect which version of the flash player was currently installed. This is a normal thing, we do it all the time when embedding flash into html, we detect which version of the player is installed and if the user has an old version they are invited to upgrade…

But what about finding the flash version from within flash? An actionscript based detection method? I hadn’t ever thought about doing that…

Actionscript 3 now uses the flash system capabilities class to report all it’s “capabilities”. First we have to import it and then we have access to all the details through the Capabilities object, such as operating system, language, pixel aspect ration and flash player version. There are a ton of others and I’ve included them in the trace statements.

Steps

  1. import the class import flash.system.Capabilities;
  2. read the version from the Capabilities object var flashPlayerVersion:String = Capabilities.version;

This returns a string, 3 letter operating system, a space, and then the version number as four numbers seperated with commas. (just like eval(‘$version’); in as2)
I display the flashPlayerVersion and to split it out I split the string on the space, and then split the version number with the comma delimiter and display them all.

Example

Here’s what mine is (gif):

flash player version detection as3

And here’s what yours is (swf):
[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/11/flashversiondetectionactionscriptmethodas3.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”160″ height=”160″]

Get Adobe Flash player

[/kml_flashembed]

Actionscript (as3)

[cc lang=”actionscript” tab_size=”2″ lines=”40″]
import flash.system.Capabilities;

var flashPlayerVersion:String = Capabilities.version;

var osArray:Array = flashPlayerVersion.split(‘ ‘);
var osType:String = osArray[0]; //The operating system: WIN, MAC, LNX
var versionArray:Array = osArray[1].split(‘,’);//The player versions. 9,0,115,0
var majorVersion:Number = parseInt(versionArray[0]);
var majorRevision:Number = parseInt(versionArray[1]);
var minorVersion:Number = parseInt(versionArray[2]);
var minorRevision:Number = parseInt(versionArray[3]);

vers.text = flashPlayerVersion;
feedback.text = “Operating System: “+osType + “\n” +
“Major Version: “+majorVersion + “\n” +
“Major Revision: “+majorRevision + “\n” +
“Minor Version: “+minorVersion + “\n” +
“Minor Revision: “+minorRevision;

trace(“Operating System: “+osType);
trace(“Major Version: “+majorVersion);
trace(“Major Revision: “+majorRevision);
trace(“Minor Version: “+minorVersion);
trace(“Minor Revision: “+minorRevision);
trace(“–other capabilities–“);
trace(“avHardwareDisable: ” + Capabilities.avHardwareDisable);
trace(“hasAccessibility: ” + Capabilities.hasAccessibility);
trace(“hasAudio: ” + Capabilities.hasAudio);
trace(“hasAudioEncoder: ” + Capabilities.hasAudioEncoder);
trace(“hasEmbeddedVideo: ” + Capabilities.hasEmbeddedVideo);
trace(“hasMP3: ” + Capabilities.hasMP3);
trace(“hasPrinting: ” + Capabilities.hasPrinting);
trace(“hasScreenBroadcast: ” + Capabilities.hasScreenBroadcast);
trace(“hasScreenPlayback: ” + Capabilities.hasScreenPlayback);
trace(“hasStreamingAudio: ” + Capabilities.hasStreamingAudio);
trace(“hasVideoEncoder: ” + Capabilities.hasVideoEncoder);
trace(“isDebugger: ” + Capabilities.isDebugger);
trace(“language: ” + Capabilities.language);
trace(“localFileReadDisable: ” + Capabilities.localFileReadDisable);
trace(“manufacturer: ” + Capabilities.manufacturer);
trace(“os: ” + Capabilities.os);
trace(“pixelAspectRatio: ” + Capabilities.pixelAspectRatio);
trace(“playerType: ” + Capabilities.playerType);
trace(“screenColor: ” + Capabilities.screenColor);
trace(“screenDPI: ” + Capabilities.screenDPI);

trace(“screenResolutionX: ” + Capabilities.screenResolutionX);
trace(“screenResolutionY: ” + Capabilities.screenResolutionY);
trace(“serverString: ” + Capabilities.serverString);
[/cc]

Download

Here’s the source fla file: flash version detection actionscript method (as3)

Copy TextField text to System clipboard | Actionscript (AS2 + AS3) Tutorial

Overview

Integrating the clipboard of the operating system with your flash projects is sometimes essential. It’s a very simple and boils down to one basic method… System.setClipboard(). I’ve found a couple other things help the user experience though, such as selecting the text that gets copied and giving the user some sort of feedback to let them know that the text was successfully copied. Here’s a simple way to do it. Have any suggestions to make it better?

I’ve included an as2 version as well as as3. I’ve promised myself to migrate to as3, so I’m not coding anything in 2 that I don’t do in 3 also. This was to discourage me from coding in as2 and to encourage me to code as3, but also let me learn by doing it in both to see the actual differences if I was stuck doing a project in as2. I figured this could help others see the differences between the two versions of actionscript a bit easier and make their own migration as well!

Steps

  1. copy to OS clipboard = System.setClipboard(“Text to COPY”) of System.setClipboard(textBoxToCopy.text)
  2. set selection to text that is copied
  3. give user feedback

Examples and Source

AS2

[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/11/clipboard_as2.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

[cc lang=”actionscript” tab_size=”2″ lines=”40″]
textBox.textBox.text = “Click this text box to copy the text or click the COPY button below. You will see feedback to the user and this text copied to your clipboard!\n\n”+
‘copyButton.onRelease = textBox.onPress = function(){\n\tSelection.setFocus(“textBox”);\n\tSelection.setSelection(0, textBox.text.length);\n\tSystem.setClipboard(textBox.text);\n\ttrace(“copied: “+textBox.text);\n\tfeedback(“Text Copied!”);\n}’;

copyButton.onRelease = textBox.onPress = function(){
Selection.setFocus(“textBox.textBox”);
Selection.setSelection(0, textBox.textBox.text.length);
System.setClipboard(textBox.textBox.text);
trace(“copied: “+textBox.textBox.text);
textFeedback(“Text Copied!”);
}

function textFeedback(theFeedback:String){
feedback.text = theFeedback;
setTimeout(function(){feedback.text=””;}, 1200);
}
[/cc]

AS3

[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/11/clipboard_as3.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

[cc lang=”actionscript” tab_size=”2″ lines=”40″]
textBox.text = “Click this text box to copy the text or click the COPY button below. You will see feedback to the user and this text copied to your clipboard!\n\n”+
‘function copyText(e:MouseEvent):void{\n\ttextBox.setSelection(0, textBox.text.length)\n\tSystem.setClipboard(textBox.text);\n\ttrace(“copied: “+textBox.text);\n\ttextFeedback(“Text Copied!”);\n}’;

//set it so the textBox selection will show even when textBox has no focus
textBox.alwaysShowSelection = true;

textBox.addEventListener(MouseEvent.CLICK, copyText);
copyButton.addEventListener(MouseEvent.CLICK, copyText);

function copyText(e:MouseEvent):void{
textBox.setSelection(0, textBox.text.length)
System.setClipboard(textBox.text);
trace(“copied: “+textBox.text);
textFeedback(“Text Copied!”);
}

function textFeedback(theFeedback:String):void {
feedback.text = theFeedback;
setTimeout(function(){feedback.text=””;}, 1200);
}
[/cc]

Download

Source files: clipboard_as3.fla clipboard_as2+as3.zip

Voters Aide, a Google Analytics Event Tracking Report Example

Overview

Voters Aide – a little flash app I made in some spare time to help prioritize the issues and positions for the 2008 presidential election. The app would let uses assign a weight to each of the big issues (0 – 100), and then read each candidates positions on every issue and record to which candidate they leaned (0 -100). The app did all the math then. Simply multiply the weight by their leaning and total it up. So if on the economy (which was reported the heaviest weighted issue overall) you say it is a weight of 90 and you lean one way +25 then your economy position is calculated 25 x .9 toward that candidate (22.5). To get a better understanding of it even though the election is over, go ahead and run through it yourself. I copied the selection of top issues and each candidate’s position from CNN’s website. I even randomized which side each candidate would show up on and left them unmarked so no one would be prejudiced toward their candidate. I wanted uses actual positions and priorities to speak louder than their preconceived preference or bias. I know this is flawed because the candidates position descriptions often were dead a give away, even sometimes saying the candidates name. Ideally it’d be great to simplify the positions but I wasn’t about to try to summarize it all! =)

Now that the election is decided though, I wanted to share what else I learned with this app. I included my google analytics event tracking methods in the voters aide app. So to everyone that has been using the app, I was watching!

Results

I used event tracking to see what weight was applied to every issue, to see which way users leaned on every issue and of course their final calculations which told them who they support. The reports are interesting because they not only tell you how many people apply a weight to an issue, but also what value. They say not only how many users actually continued through each issue and stated which way they lean, but also how far they lean and who they lean to! Not only how many users actually completed voters aide to the final screen which shows their calculation, but also which candidate they supported in voters aide and even by how much!
The results were very interesting in the weights people used to prioritize the issues. Maybe that is because is is easier to visualize? But the issues were ranked in the following order:

Label Total Events Unique Events Event Value Avg. Value
1.economy70605,25875.11
2.education63554,54872.19
3.iraq46373,22070.00
4.energy67574,57968.34
5.taxes40382,64166.02
6.homeland security50433,26465.28
7.health care59533,78964.22
8.afghanistan64474,06863.56
9.housing50393,12562.50
10.social security33292,00960.88
11.abortion92585,54460.26
12.environment56483,32459.36
13.iran40372,26656.65
14.free trade41362,22454.24
15.israel38362,04853.89
16.guns49422,46150.22
17.russia31251,55050.00
18.stem cell research27261,29648.00
19.LBGT37311,75047.30
20.immigration38331,74946.03
21.cuba57472,15137.74

Here is an example of the report for the most important issue, economy. It stats which candidate had the users support and even how many times and the average value.

Label Total Events Unique EventsEvent Value Avg. Value
1.supportmccain26241,54559.42
2.supportobama23191,43562.39
3.supportno2100.00

I’ll go ahead and say, (although the app was not designed to predict the president or even considered your location, it just counted how many times it reported to users which candidate they leaned towards) according to Voters Aide, John McCain would have won the election.  So more people who used Voters Aide lean McCain in the end, once they get to the end of the issues. I’d have to add that this is a very small sample size and even if it were larger, I never tested the app for usability and user understanding, so the end result doesn’t mean that much in the end. But as you will be curious here is the report for the final page events:

Label Total Events Unique Events Event Value Avg. Value
1.JOHN MCCAIN27212,23982.93
2.BARRACK OBAMA19151,55581.84
3.NO ONE12101,200100

Anyways, great election. I hope all this change will be a change for the better.

Congratulations to everyone who is excited about the future & condolences to everyone lamenting the end of the world.

Voters Aide | Prioritize the Issues this Election | Interactive Flash App

To accompany the last presidential debate, I ask a question:

Who to vote for?

It’s not just about what party you’re affiliated with, who you agree with more on an issue or which candidate you understand better… it’s a combination of them all. It’s more important how a candidate can handle the different issues facing us today than how they perform in a debate or advertisement.
There should be somewhere to assign a weight to each issue on the table and then issue by issue see which candidate I agree more with. Then it would calculate and tell me who I really support according to how I prioritize the issues. So if I think the only issue worth voting about is Iraq or the economy and I agree more with Barrack Obama or John McCain on those issues it will be reflect in the results.
It’s pretty hard to explain the whole idea, without building it myself, so that’s just what I did… while I couldn’t stop thinking about it I coded it.

Check it out, and I hope it helps! Cause we’re gonna need all the help we can get on this one! It can help you decide or just test yourself and see if you really support that candidate as much as you think.

Go try it here!

I pulled info from CNN’s election center mostly because all the info was gathered for me already, each of the big issues, descriptions and the candidates position. I have a slider for each issue where users select how imortant it is to them (on a scale of 0 to 100 percent). Then users compare their own position on the issues with each candidate (on a scale of 0 to 100 toward each candidate). This is all considered while your support is calculated. Each issue’s importance as a percentage is multiplied by the amount you agree with each candidates position. These are all added up and totaled to give a final percentage. This is innovative in that it’s not just who you agree with mpre, it’s who you agree with more on the isues that you think are more important! Let me know what you think about this and let the candidates know what you think about their positions.

Voters Aide the flash app to help you decide who you support by letting you prioritize the issues and choose which candidate you lean towards on each issue and see the overall results.

Event Tracking with Google Analytics | Flash Integration | Tutorial

Many have read my Integrate Google Analytics with Flash Tutorial in which I express enthusiasm for the new event tracking at google analytics! Well, it’s been a while, but I was admitted to the Beta testing group! So I’ve now had the chance to play with event tracking a bit and wanted to publish my findings!

Overview

Almost a year ago Google Analytics announced their new event tracking model and have had help documents published and code samples up. And as with many of Google’s products the beta stamp has lasted a very very long time. Many have seen my earlier tutorial exploring using traditional Google Analytics Tracking from within Flash, and it does wonders to track your flash apps in this manner, but there is a problem with it. We’re using supposed object oriented concepts to track objects as pageviews. One thing is it really isn’t a very intuitive way to represent that data, and another it inflates your pageviews! The solution? the long awaited and announced Event Tracking model. I’ve been itching for this to be released so I could refresh my analytic tactics I use in my flash projects. No, to answer your questions, it has not been released yet, but I contacted Google and explained that I would be a great beta tester for this feature and after a bit of correspondence they invited me to join in the beta testing! This is good news for you too! Because I will tell you all about how to do it and even show you what the reporting looks like and when it is released finally, you will know what you’re in for after this sneak peak!

UPDATE: Here are the reports for this very example: Report from Event Tracking with Flash Tutorial

The very quick summary is this:
_trackEvent(category, action, optional_label, optional_value)
Note that the _trackEvent function is called on the pageTracker object itself. (initially Google had you instantiate a separate event tracker for every object (or category) you wanted tracked)

For example, if we want to track a ball. All the actions that can apply to the ball are: it being created, dragged, dropped, bounced, deleted… You get the idea. We can have direct user actions tracked or even automatic actions. If we have gravity and physics running, the ball may bounce a lot without any direct user interaction. But it will never be dragged or dropped without direct interaction. I’d recommend only tracking user interactions because who cares how often a ball bounces on your page (unless you’re doing an experiment, of course), want we want to know is how and when a user interacts with the ball.

category:string (required)

This is the name of the object you are tracking.

action:string (required)

This is the action that happens to your object you want to track.

optional_label:string (optional)

This can be more information to accompany the action.

optional_value:integer (optional)

A number to provide numerical information to accompany the action.

Steps

  1. First, I’d recommend reading up about Event Tracking at Google
  2. Decide your object oriented structure for tracking events. What objects do you want to track and what useful information do you want to get through tracking user interaction?
  3. Make sure you have the new Google analytics tracking code on your page
  4. Use these functions to communicate Google Analytics from your flash
    1. Call the main function with the specified parameters
    2. It will call the appropriate function and send the data to your pageTracker object through javascript with externalInterface calls
  5. See the reports in your analytics profile! (if your a beta tester, or else, wait until it is released)

Source code

The tracking functions are below, I enhanced the earlier trackGA function I wrote about. Now you call trackGA with 2 required parameters, categoryOrPageTrack and action. categoryOrPageTrack is where you have to pay attention. I wanted to keep the ability to track pageviews as well as have event tracking, so as the first param you either send in the string ‘page’ to explicitly state that you want to track the page view, or you send in another string to state you want to track an event on that specified object. Action remains the same, the action you want tracked (either on the pageview, it is the path that will appear in your reports; or the event tracking will be the action tracked to the category)…
So to track a pageview I call
trackGA("page", "swfLoaded");
and to track an event to an object I call ball:
trackGA("ball", "created");
The trackGA function will rout your call to the appropriate place and send the info to Google through either the trackGAPage function or the trackGAEvent function.
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
//trackGA (categoryOrPageTrack [required], action [required], label [optional], value [optional]
//categoryOrPageTrack – either the category string or a string saying ‘page’
function trackGA(categoryOrPageTrack:String, action:String, optional_label:String, optional_value:Number) {
//call page tracking version of Google analytics
if (categoryOrPageTrack == “page”) {
//trace(“GATC pageTracker call”);
trackGAPage(action);
}
//call event tracking method
else {
//trace(“GATC event tracker call”);
trackGAEvent(categoryOrPageTrack, action, optional_label, optional_value);
}
}

var prefix:String = “flashGA”;
//Google Analytics Calls Page Tracking – for tracking page views
function trackGAPage(action:String) {
//GA call
if (prefix != null && !eventTrack){
var call = “/” + prefix + “/” + action;
//Old Google Analytics Code (urchinTracker)
ExternalInterface.call(“urchinTracker(‘”+call+”‘)”);
//New Google Analytics Code (_trackPageview) pageview
ExternalInterface.call(“pageTracker._trackPageview(‘”+call+”‘)”);
trace(“==GATC==pageTracker._trackPageview(‘”+call+”‘)”);
}
_root.tracer.text = action;
}

//Google Analytics Event Tracking Calls – for tracking events and not pageviews
//category, action, label (optional), value(optional)
function trackGAEvent(category:String, action:String, optional_label:String, optional_value:Number) {
/*
objectTracker_trackEvent(category, action, optional_label, optional_value)
category (required) – The name you supply for the group of objects you want to track.
action (required) – A string that is uniquely paired with each category, and commonly used to define the type of user interaction for the web object.
label (optional) – An optional string to provide additional dimensions to the event data.
value (optional) – An optional integer that you can use to provide numerical data about the user event.
*/

theCategory = “‘” + category;
theAction = “‘, ‘” + action + “‘”;
theLabel = (optional_label == null) ? “” : “, ‘” + optional_label + “‘”;
theValue = (optional_value == null) ? “” : “, ” + optional_value;
//New Google Analytics Code (_trackEvent) event tracking
theCall = “pageTracker._trackEvent(” + theCategory + theAction + theLabel + theValue + “)”;
ExternalInterface.call(theCall);
trace(“====GATC====”+theCall);
_root.tracer.text = theCategory + theAction + theLabel + theValue;
}
[/cc]

Here’s the actionscript lines where I call the trackGA function:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
//Tracks that the swf loads, so I pass ‘page’ to let it know I want a pageview tracked…
trackGA(“page”, “swfLoaded”);
//Tracks various objects sending various actions
trackGA(“gravity”, “on”);
trackGA(“gravity”, “off”);
trackGA(“friction”, “on”);
trackGA(“friction”, “off”);
trackGA(“ball”, “deleted”, count);
trackGA(“ball”, “created”, ballCount);
trackGA(“ball”, “drag”, this.ballNum, this.ballNum);
trackGA(“ball”, “drop”, this.ballNum, this.ballNum);
trackGA(“ball”, “bounce”, “right”, this.ballNum);
[/cc]

Example

[kml_flashembed fversion=”9.0.0″ movie=”/wp-content/uploads/2008/10/integrategoogleanalytics/integrategoogleanalytics.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”400″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

View example in it’s own html page, I even added a couple html buttons with javascript hooked in to show javascript event tracking implementation.

Download

Download Source

Concerns

I’ve noticed while putting this together that the calls to google analytics are not completely fullfilled, this example sends out correct calls to javascript, but (in firefox at least) a max of about 1 tracking call is registered with the tracking code every 5 seconds or so. I noticed this as I was monitoring the drag and drop events for each ball, although the drag and drop events are both fired, usually the drag event was received and the drop is not. After verifying that my code was consistent, I noticed that no matter how fast I interacted with the objects, the calls were much slower. I’m guessing this is a limit placed by the google team to keep us from sending pointless data such as is posted at the bottom of the event tracking implementation guide, titled Events Per Session Limit.

Interactive Image Viewer v1 @ FlashDen

I’ve re-purposed an old project of mine, the interactive pog portfolio viewer, to activeden. I call it the pog portfolio because each work is represented by a circle, or pog, and you play ith it in the “bay” with different interactive physics configurations. When you click a pog you can view a close up image of that item and more details. The whole file has been cleaned up (code and graphics) and documented for easy customizations.It is a small file size as well, under 36kb swf!

This is mainly an image viewer, stay tuned for any updates, like video support etc.

INTERACTIVE IMAGE VIEWER WITH PHYSICS AND ANIMATION EXAMPLE!

pog portfolio image

View Details here at activeden

Works and configuration loaded in through a single xml file. Select works from the bay to view title, description image and a link (if applicable). Organize works with the tags or select all and choose the physics of the bay for interactivity control (gravity, spring, grid and friction).

It is fully customizable and fully driven by xml. The xml file contains values for configuring the swf, and also all the information about each work to be included in the portfolio.

Each work is loaded into the ‘bay’ as a round thumbnail or ‘pog’. These pogs are animated with the interaction options (gravity, friction, spring and grid). The pogs are sortable by tags (parsed in from the xml).

The whole color scheme of the image viewer is configurable, or can even be set to random! Have a different color scheme every time your image viewer loads!

Clicking a pog in the interactive bay sends that thumb to the holding area and loads the close up into the focus window for that work. It also loads the details about that work into the detail box (to the right of the focus box). Each works needs a 50×50 thumbnail and a close up (max 375px x 270px) image. Focus images are all loaded in with an informative preloader and fade is once loaded.

Site easily integrates with Google Analytics to track user interactions within this flash portfolio!

All works in the portfolio are passed in through an external xml file, here is a sample work node from xml:
[cc lang=”xml” tab_size=”2″ lines=”40″]


Random Gear

Random gear photograph from activeden assets.

random_gear.jpg


random_gear.jpg

http://activeden.net


Photo|Industrial

[/cc]

Download source at activeden

Enjoy, and let me know what you think!

Circlecube Flash Items on activeden

21075 24687 45713 45893 22018