Date: 15 July 2010
Recently I've been creating more and more full flash sites. Nice projects and a good way to put your creativity in. If I say so... But sometimes when running in the browser something happens and the flash element stops working properly. When using the localTrusted player (CTRL + ENTER in Flash CS4) you'll see some nice traces (if ofcourse you entered any). So here is a small debug tool for just those cases. Maybe some of you heard of Arthropod. Wouldn't it be nice if you could create something simular?
Download the project here
First of all, create the UI
- Place a TextArea component on the stage called 'textAreaComponent'
- Place a Button in the left corner of the stage called 'clearButton'
- Make sure you publish this file as an AIR project later on
- Create a new baseclass "Main.as":
package
{
import flash.display.MovieClip;
import flash.text.TextFormat;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.controls.TextArea;
import flash.net.LocalConnection;
public class Main extends MovieClip {
/** @private */
private var _localConnection:LocalConnection;
private var _lines:Array = [];
/** @const */
private const TEXTAREA_MARGIN:Object = { left: 5, top:25, right:5, bottom: 33 };
// ________________________________________________________________________________ constructor
public function Main() {
stage.align = 'TL';
stage.scaleMode = 'noScale';
stage.addEventListener(Event.RESIZE, _resizeHandler);
_resizeHandler();
_setupLocalConnection();
_setupTextArea();
clearButton.addEventListener(MouseEvent.CLICK, _clickClear);
};
// ________________________________________________________________________________ setup
private function _setupLocalConnection():void {
_localConnection = new LocalConnection();
_localConnection.client = this;
_localConnection.allowDomain('*');
_localConnection.connect('_debugger');
};
private function _setupTextArea():void {
var txtFormat:TextFormat = new TextFormat();
txtFormat.font = 'Courier New';
textArea.setStyle('textFormat', txtFormat);
};
// ________________________________________________________________________________ receive method
public function receive($method:String, $messages:Array):void {
switch ($method) {
case 'log':
_appendText($messages);
break;
case 'error':
_appendText($messages, 0xff0000);
break;
}
};
// ________________________________________________________________________________ getters / setters
public function get textArea():TextArea {
return this.textAreaComponent;
};
// ________________________________________________________________________________ event handlers
private function _resizeHandler(e:Event=null):void {
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
textArea.x = TEXTAREA_MARGIN.left;
textArea.y = TEXTAREA_MARGIN.top;
textArea.width = w - TEXTAREA_MARGIN.left - TEXTAREA_MARGIN.right;
textArea.height = h - TEXTAREA_MARGIN.top - TEXTAREA_MARGIN.bottom;
clearButton.y = h - clearButton.height - 5;
};
private function _clickClear(e:MouseEvent):void {
_lines = [];
_writeLog();
};
// ________________________________________________________________________________ write log
private function _appendText($text:Array, $color:uint=0x000000):void {
_lines.push([$text, $color]);
_writeLog();
}
private function _writeLog():void {
var html:String = '';
for each (var line:Array in _lines) {
html += '' + line[0].join(' ') + '
';
}
textArea.htmlText = html;
textArea.verticalScrollPosition = textArea.maxVerticalScrollPosition;
};
}
}
Add Debug to your global classpath
package {
import flash.net.LocalConnection;
import flash.events.StatusEvent;
public class Debug {
/** @private */
private static var _localConnection:LocalConnection;
private static var _lastMessage:String;
// ________________________________________________________________________________ logging
public static function log(... $args):void {
_send('log', $args);
};
public static function error(... $args):void {
_send('error', $args);
};
private static function _send($method:String, $message:Array):void {
_setup();
_lastMessage = $message.join(' ');
trace('[DEBUGGER]', $message.join(' '));
_localConnection.send('_debugger', 'receive', $method, $message);
};
// ________________________________________________________________________________ set-up
private static function _setup():void {
if (_localConnection == null) {
_localConnection = new LocalConnection();
_localConnection.addEventListener(StatusEvent.STATUS, _statusHandler);
}
};
// ________________________________________________________________________________ event handler
private static function _statusHandler(e:StatusEvent):void {
};
}
}
Create a test flash element
Now just create a new flash file and use the following methods:
Debug.log('This will appear in the AIR debugger');
Debug.error('Something went wrong, or not ...');
Start the debugger air application and run your new flash app (with the above code) and you'll see messages appear from within the debugger, triggered by another flash app.
Date: 17 June 2010

AMFPHP is a stable factor in the flash community for communication between server and client-side.
Before AMFPHP flash developers used XML files, GET or POST methods to read and send data to the server.
The late 2003 Wolfgang Hamann reverse-engineered the AMF (Action Message Format) format to craete a working (PHP) gateway. And AMFPHP was born.
This way client applications can directly call PHP class methods. Jut follow the following steps and you'll be ready to use AMFPHP in a couple of minutes.
Read more ...
Date: 16 June 2010
A few people mailed me how I created this flash blog, and especially how I managed to "blend" it with the HTML scrollbar.
My first attempt had an easier solution, just to resize the HTML <object> element to it's boundaries. The only big problem with this approach is that the maximum height of an HTML flash <object> is around 4,000 pixels. Anything higher will cut of the content of the flash element. So I came up with a solution that simulates a very large flash object.
Don't have any idea what I'mt talking about? Check this example
Setting up HTML & CSS
I could copy paste the HTML code here, but it's best just to check out the source
over here
The following CSS lines are enough :
html,body { margin:0; padding:0; height:100%; }
#flashPlaceholder { width:100%; height:100%; }
#flashContainer { width:100%; height:100%; position:fixed; /* important */ }
Setting up Flash
I wrote a small package that handles page resizes and HTML scroll events.
In short: Once the boundaries of the flash object (internally) change, the external interface will call a javascript function telling the DOM that it should resize it's placeholder.
And on the other side javascript tells flash to move it's main container once the scrollbar is used.
package {
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.external.ExternalInterface;
import flash.geom.Rectangle;
public class HTMLDomResizer
{
// Super privates
private static var __self:DisplayObjectContainer;
// Normal private variables
private static var _containerInfo:Object = { w: 0, h: 0 };
/**
* Psuedo constructor
*
* @param $self The MainTimeline object
*/
public static function init($self:DisplayObjectContainer):void {
__self = $self;
__self.root.stage.align = 'TL';
__self.root.stage.scaleMode = 'noScale';
_initExternalInterface();
}
/**
* Set up the external interface
*
* @return void
*/
private static function _initExternalInterface():void {
if (!ExternalInterface.available) { throw new Error('ExternalInterface unavailable'); }
// Listen for incoming javascript calls
ExternalInterface.addCallback("flashScroll", function(... $args):void {
__self.x = -$args[0];
__self.y = -$args[1];
});
// Check if the dimensions of this flash content is changed
__self.addEventListener(Event.ENTER_FRAME, function ($e:Event):void {
var bounds:Rectangle = __self.parent.getBounds(__self);
// Only call the resize function if the content is actually changed, else flash will keep fireing useless js calls
if (bounds.x + bounds.width != _containerInfo.w || bounds.y + bounds.height != _containerInfo.h) {
_containerInfo.w = bounds.x + bounds.width;
_containerInfo.h = bounds.y + bounds.height;
_resizeFlashContent();
}
});
}
/**
* Call a javascript function to tell the DOM to resize the placeholder DIV
*
* @return void
*/
private static function _resizeFlashContent():void {
ExternalInterface.call("resizeFlashHandler", Math.ceil(__self.width), Math.ceil(__self.height));
}
/**
* Scroll the HTML DOM to a specific position through javascript
* @param int $x
* @param int $y
*/
public static function scrollTo($x:int, $y:int):void {
if (__self === null) { throw new Error('Not initialized yet'); }
if (!ExternalInterface.available) { throw new Error('ExternalInterface unavailable'); }
ExternalInterface.call("window.scrollTo", $x, $y);
}
}
}
Setting up Javascript
One of the most important steps is javascript. In order for flash to manipulate any DOM elements.
Just check out
the source of the javascript file.
The most important function (ofcourse they're all important), is resizeFlashHandler():
This function resizes the placeholder to so it always fits the total screen or it will resize the placeholder giving the DOM a scrollbar.
You can also change the "minimumWidth" variable, so your flash element can be wider (or smaller)
/**
* Function is called from the external interface in flash
* It passes on the width and height of the flash element internally
*
* @param {int} width
* @param {int} height
*/
function resizeFlashHandler(w, h) {
lastResizeHandler = [w, h];
var viewPortSize = getViewportDimensions(),
container = document.getElementById('flashPlaceholder');
if (w && h) {
if (h < viewPortSize[1]) {
container.style.height = "100%";
} else {
container.style.height = h + "px";
}
}
if (viewPortSize[0] < minimumWidth) {
container.style.width = minimumWidth + "px";
} else {
container.style.width = "100%";
}
scrollHandler();
}
Finally
If you put all those things together, you'll get the site you're currently looking at.
You can
download the example files here or
check out a small example
Date: 9 June 2010
I came across a small issue when creating a 3d object in the flash cs4 ide environment.
When you creata a cube from 6 panes and you want to rotate it on it's x, y and or z axil the following problem occurs:
As you can once the cube is rotated the panes' z-index get's distorted.
To fix this problem you have to calculate every frame and sort the display list according
to it's z position.
Lee Brimelow came with an easy SimpleZSorter class, which worked fine in some occasions, unfortunately not for me.
The problem with the above solution is that it uses the z position, instead of using the observer's point of view.
So I came up with a simple solution
The following example demonstrates this:
This example has a small sorting issue, this is because it's loaded into this blogpost, which gives it some problems
And the code that made it possible:
function autoZSort($cube:DisplayObjectContainer):void {
var faces:Array = [];
var i:int;
var curMid:Vector3D;
var pp:PerspectiveProjection = root.transform.perspectiveProjection;
observerPos.x = pp.projectionCenter.x;
observerPos.y = pp.projectionCenter.y;
observerPos.z = -pp.focalLength;
var mc:DisplayObject;
for(i = 0; i < $cube.numChildren; i++){
mc = $cube.getChildAt(i);
curMid = mc.transform.getRelativeMatrix3D($cube.root).position.clone();
faces.push({mc: mc, dist: Math.sqrt(Math.pow(curMid.x - observerPos.x, 2) + Math.pow(curMid.y - observerPos.y, 2) + Math.pow(curMid.z-observerPos.z, 2)) });
}
faces.sortOn("dist", Array.NUMERIC | Array.DESCENDING);
for (i = 0; i < faces.length; i++) {
cube.setChildIndex(faces[i].mc, i);
}
}
You can download the .fla here (56 kb)
Date: 11 March 2010
Step 1
Installing the fonts
Make sure you have installed all the fonts you want to use.
For Windows: Copy / paste them into
C:\WINDOWS\Fonts\
For OSX: Double click the desired font(s) and click on the "Install font" button
Step 2
Install the ExportFonts extension
Download the extension and install it by double clicking
Step 3
Creating a new flash file
Create a new Flash ActionScript 3.0 CS4 file (CTRL + N) and save it.
Step 4
Launch
Go to Window > Other panels > ExportFonts.
You'll see a small multiline textfield with a few fonts seperated by a comma.
Fill in the installed fonts and press "GO!". A map
swf_fonts is created where the exported SWF font files are exported to.
In the following steps I'll explain how you can use those fonts.
Read more ...
Date: 10 March 2010
During the creation of a Flash CS4 Codebase panel I found myself struggling around a simple feature in this panel: Opening a folder in the local file system.
This might look like an easy task, but unfortuantely I couldn't find anything close to what I was aiming for in the Flash CS4 Resource.
So I started another google quest for a satisfying answer and luckally for me (and you) I found a simple solution using the FLfile.runCommandLine method
// Windows approach
MMExecute('FLfile.runCommandLine("cmd /C explorer C:\\folder\\to\\open\\");');
// OSX
MMExecute('FLfile.runCommandLine("exec /Path/to/folder");');
The
/C means: Carries out the command specified by string and then terminates.
And don't forget the double backslashes for the Windows example
Date: 4 March 2010
"Adobe® Stratus 2 enables peer assisted networking using the Real Time Media Flow Protocol (RTMFP) within the Adobe Flash® Platform. RTMFP is the evolution of media delivery and real time communication over the Internet enabling peers on the network to assist in delivery. Stratus was first introduced in 2008 as a rendezvous-only service that allowed clients to send data from client to client without passing through a server. Adobe Flash Player 10, which debuted peer assisted networking, has been adopted today by over 90% of all internet connected PCs."
With adobe launching it's RTFMP network called Stratus the first tutorials and beta reviews appeared online, only all of them were written for Flex. So here is a small tutorial on how to set up a RTFMP peer-to-peer connection using only Flash CS4 and the latest 10.1 runtime.
- Example (Connecting takes same time, be patient)
- Download source
Setting up
- Buy (or
download a trial) Adobe Flash CS4
-
Download Flash Player 10.1 SWC (scroll down)
-
Sign up for a beta developer key
- You might want to read
this article about Adobe Stratus 2
Read more ...
Date: 25 February 2010
A collection of self-made functions (aka snippets) to speed things up.
1. Check if an e-mail is valid
2. First character in uppercase
3. Random number
4. Shuffle an array
5. Does an element exist in an array
6. Remove an element from an array
7. The AS2 setRGB method
8. Reverse timeline animation
9. Get the file extension
10. Filesize
11. Hexadecimal to RGB object
12. Color to monochrome color
13. Crop a bitmap
14. Forces to run the garbage collection
15. Local to global position
Read more ...
Date: 22 February 2010
About 50% of all my flash projects I used dynamic textfields that resizes according to it's content.
And ofcourse my blog would not be here if textfields were unable to auto resize. Unfortunately the autoSize property is not working well in some cases. First of all take a small peak at the autoSize documentation here.
The problem most of the time occurs on multiline textfields.
Some glitches of the autoSize property
- TextField height is not accurate.
- TextField allows vertical scrolling.
- No trimming
So I started playing around with the textHeight, mouseWheel and scroll event and left the autoSize as it is and I came up some interesting stuff.
Read more ...
Date: 14 February 2010
With the birth of AS3, actionscript -and flash in particular- grew up and became more and more suitable for professional web and desktop based solutions. But like any scripting (or programming) languages you need to keep an eye on your performance. Building astonishing and complex projects is ofcourse very satisfying, but can be also a big pain in the ass when your client uses a machine from the early nineties.
What a client expects
Developing huge 3d projects with fullscreen videos won't render that well on machines that already have a lot of trouble with starting notepad. But as long as the client knows flash can achieve miracles, but it can't cure deseases, you're in the right zone.
Project cycle
Nevertheless always be on top of your game as it comes to performance. If you start new (large) projects and keep focussing on performance from the very first line of code you write and monitor your result alongside the entire process you won't get any unpleasant suprises once your client tests your final version.

Illustrated on the graph above, the further away you are in a project the more difficult it gets for the developer to add new functionality in it's code.
So if you could be warned in an early stage of the flashproject cycle that a particular update is using too much system recourses or the framerate is at an unacceptable level, you could take measures and therefor avoiding the 'last minute' adjustments. Which -we all know- will only decrease the quality of your code and the project itself.
This exactly is the reason why you need to keep monitoring and making your code use as little resources as possible. Click the 'read more' link below, to see a few examples and best practices in maximizing flash perfomance
Read more ...
Date: 9 February 2010
I've been thinking about it for a while. And finally I convinced myself to start my personal blog. For, ofcourse, sharing my flash knowledge and experimenting with different approaches. And alongside keeping the social media phenomen 'personal branding' in the back of my head.
After designing the blog and halfway through the development stage I started wondering; "I'm creating a blog (mainly) about flash, but the blog itself is in 'plain' HTML".
Why not make the blog completely in flash.
So that's exactly what I did. First I converted the design to a flash equivalent and after some headaches and (for me) new (read 'annoying') glitches in the HTML render engine of flash, which ofcourse isn't as half as advanced as the HTML render engines of the most recent browser suchlike firefox, safari or chrome.
Nonetheless I think a blog can be successful even with very limited HTML functionality available.
So every pixel you see on this blog is created with flash using ActionScript 3.0. Along the way I stumbled upon some fascinating and a lot of frustrating issues. The biggest one would be the HTML textfield, which is the heart of any blog. The current HTML capabilities in flash are limited, but at this stage I recon it's more then acceptable.
With the upcoming new Creative Suite release of Adobe, and Flash expanding it's professionalisation project I think in the nearby future HTML text rendering would become more flash suitable.
Anyway, I hope I'll be able to maintain and keep updating this blog on a regular basis so I'd be able to contribute in the growing flash / webdevelopment community.
And oh yes, don't forget to follow me on twitter and subscribe to my RSS feed.