Tag Archive for 'as3'

Flash Strandbeest

Some weeks ago Marc Thiele showed me a link that was about the kinetic sculptures from Theo Jansen. If you do not know about him yet check out strandbeest.com. There are a couple of videos on YouTube describing the technique behind those sculptures (click me).

Now I just saw a demo from APE which has that model built in Flash using their engine. So lovely!

Lists faster than Array

Since we are planing to release a detailed paper about AS3 optimizations and techniques I was thinking about another optimization for one of the daily problems. Looping through an array that contains objects. The fastest code to do this is

[as]for (;i {
v0 = array[i];
l = v0.length;
}[/as]

v0 is a local variable for my custom class which looks like this

[as]class Vector3D
{
public var x: Number;
public var y: Number;
public var z: Number;

public function Vector3D( x: Number, y: Number, z: Number )
{
this.x = x;
this.y = y;
this.z = z;
}

public function get length(): Number
{
return Math.sqrt( x * x + y * y + z * z );
}
}[/as]

Looks like from a real scenario. You can replace the vector class also with a particle class or whatever. It does not matter. The point is this loop takes 272ms for 1000000 iterations. It is pretty good already but if you add one more parameter to the Vector3D class you can get even faster. This is my modified Vector3D called LVector3D

[as]class LVector3D
{
public var x: Number;
public var y: Number;
public var z: Number;

public var next: LVector3D;

public function LVector3D( x: Number, y: Number, z: Number )
{
this.x = x;
this.y = y;
this.z = z;
}

public function get length(): Number
{
return Math.sqrt( x * x + y * y + z * z );
}
}[/as]

There is a public variable now called next. This variable will always point to the next LVector3D object. The exact same loop takes about 260ms.

[as]var v0: LVector3D = start;
for (;i {
l = v0.length;
v0 = v0.next;
}[/as]

You see how nice this looks? No ugly [] etc. Our variable is directly typed. And we can speed it up even more! If we replace the for(...) part with while( v0 ) it goes down to 249ms. What is also nice about a linked list is that you could add an easy splice functionality or functions to remove elemts from a list. You just have to change the next reference. If you also add a prev variable it becomes even more easy and you could loop backwards.

Building that list of vectors is also very easy. And it looks beautiful. Compare this

[as]for ( var i: int = 0; i < n; ++i )
array[ i ] = new Vector3D( i, i, i );

var v3d: LVector3D = start;

for ( var j: int = 1; j < n; j++ )
v3d = v3d.next = new LVector3D( j, j, j );[/as]

The start variable is defined in the class as private const vector3d: LVector3D = new LVector3D( 0, 0, 0 );. Very nice. Of course not useful in every case but sometimes if you have to squeeze out what is possible here is another method. So stay tuned for our paper.

Run-time file uploads

Very useful. Including source-code for real file uploads with run-time generated content.

AS3 Proxy Example

Some people have problems with the migration from AS2 to AS3. First of all. This post will not help you to migrate. Also using the stuff here is bad. I just thought I can share some idea I had and make nice use of the Proxy class you have with AS3. Why is it bad? It will make your project run slower.

First of all. What can you do with Proxy? The proxy is defined as a dynamic class and it allows you to override any method and also the “delete” operator for instance. Back to the problem: Someone said “why can I not use clip0.clip1.clip2” any longer. Another friend told me it took him some time to figure out he has to use getChildByName( 'clip0' ).getChildByName( 'clip1' ).getChildByName( 'clip2' ). By making use of the Proxy class we can give this possibility back to the users.

Since I am a nice guy I added also _x, _y, _xscale and _yscale. Now how to do that? You define a proxy that holds a Sprite object (actually… not really. More on that later). Then you have to override a lot of methods like this:

[as]flash_proxy override function getProperty( name: * ): *
{
if ( sprite.hasOwnProperty( name.toString() ) )
{
return sprite[ name.toString() ];
}
else
{
var displayObject: DisplayObject = sprite.getChildByName( name.toString() );
return ( displayObject is AS2SpriteHandle ) ? ( displayObject as AS2SpriteHandle ).handler : displayObject;
}
}[/as]

This may look a little bit fancy for the first time but what do we do? We check if the Sprite object already has that property. If so we return it. Otherwise we return the child of that sprite. Now you see that I check if the DisplayObject is a AS2SpriteHandle. That is the instance the AS2Sprite (our Proxy) stores. Because it keeps a reference back to its AS2Sprite object we can return the AS2Sprite object. If we return only Sprite we could do a.b but not a.b.c because for b we would return just Sprite and lose therefore the ability to add c just as a property.

This is important. The class AS2Sprite extends Proxy and not Sprite. Therefore I added some functions like toSprite() etc. Have a look. Examples help me often the most. And if you are a lazy guy that does not really want to bother with the AS3 syntax you might find this helpful as well.

Some example code what you can do with it:
[as]var sprite: AS2Sprite = new AS2Sprite;
addChild( sprite.toSprite() );//doh! default app is still sprite :(

sprite.clip = new AS2Sprite;

sprite.graphics.beginFill( 0xff0000, 1 );
sprite.graphics.drawCircle( 0, 0, 10 );
sprite.graphics.endFill();
sprite._x = 10;
sprite._y = 10;

sprite.clip.graphics.beginFill( 0×00ff00, 1 );
sprite.clip.graphics.drawCircle( 0, 0, 10 );
sprite.clip.graphics.endFill();
sprite.clip._x = 50;
sprite.clip._y = 50;

sprite.clip.clip2 = new AS2Sprite;
sprite.clip.clip2.graphics.beginFill( 0×0000ff, 1 );
sprite.clip.clip2.graphics.drawCircle( 0, 0, 10 );
sprite.clip.clip2.graphics.endFill();
sprite.clip.clip2._x = 50;
sprite.clip.clip2._y = 50;

delete sprite.clip.clip2;//remove the blue one[/as]

A hint of true overloading

This morning I came across some strange sort-of overload workaround that can cast your class to any type. Imagine you want to have a reference to a boolean. You have to “box” it then. It look like this:

[as]class BoxedBoolean
{
private var value: Boolean;

public function BoxedBoolean( value: Boolean )
{
this.value = value;
}
}[/as]

Now doing something like if ( boxedBoolean == true ) is not possible since boxedBoolean is type BoxedBoolean. Even though the value we want to use is a boolean value. So here is the workaround:

[as]class BoxedBoolean
{
private var value: Boolean;

public function BoxedBoolean( value: Boolean )
{
this.value = value;
}

public function toString(): Boolean
{
return value;
}
}[/as]

Do not ask me what strange nature toString() has but it works. Now the only problem with this is that if ( a == true ) works fine but if ( a ) is always true.

Here is an example

[as]var b0: BoxedBoolean = new BoxedBoolean( true );
var b1: BoxedBoolean = new BoxedBoolean( false );

trace( b0 is Boolean );
trace( b1 is Boolean );

trace( b0 );
trace( b1 );

if ( b0 == true )
trace( ‘b0 = true’ );
else
trace( ‘b0 = false’ );

if ( b1 == true )
trace( ‘b1 = true’ );
else
trace( ‘b1 = false’ );[/as]

The trace output is then

false
false
true
false
b0 = true
b1 = false

If you remove the == true you will get that both b0 and b1 are true. I do not think that there is much use for it but it is interesting what you can do. toString() can also return an integer and it works as well.

How high can you get?

:o)Actually this frame-rate is not faked. It is not the actual screen refresh rate. This means you do not have 65.000 new screens during one second, but, and that is the funny thing: you have 65.000 executions of a function in one second. This is an evil hack and slows down the whole display stuff of Flash. So you can not use this in any of your projects but it is funny to watch. I think you can get higher, I was just lazy and got tired searching for the best settings.

So there is no use for this. Just fun to watch :)

By the way the initial idea came from André Michelle. The competition is open, ha! How high can you get?

Looking up the calling function

Ralf Bokelberk had a nice idea about how to get dynamically to the function name of the calling function. This may sound a little bit wired, but if you do debugging it is nice to do something like Logger.add( 'log this infomration', ... ); and then have the output with the calling function (and maybe line number).
For instance something like com.test.package::Class/function(): log this information.

Now the solution Ralf had is throwing an error and get to the whole stuff by using the stack trace. This works pretty well. In debug mode you can also send line-numbers and file information to your log output which is very nice.

[as]var stackTrace: String;

try { throw new Error(); }
catch ( e: Error ) { stackTrace = e.getStackTrace(); }

var lines: Array = stackTrace.split( “\n” );
var isDebug: Boolean = ( lines[ int( 1 ) ] as String ).indexOf( ‘[' ) != int( -1 );

var path: String;
var line: int = -1;

if ( isDebug )
{
var regex: RegExp = /at\x20(.+?)\[(.+?)\]/i;
var matches: Array = regex.exec( lines[ int( 2 ) ] );

path = matches[ int( 1 ) ];

//file:line = matches[2]
line = matches[ int( 2 ) ].split( ‘:’ )[ int( 2 ) ];//windows == 2 because of drive:\
}
else
{
path = ( lines[ int( 2 ) ] as String ).substring( 4 );
}

msg = path + ( line != -1 ? ‘[' + line.toString() + ']‘ : ” ) + ‘: ‘ + msg;[/as]

The framerate hack

976 fpsDo you worry about your frames-per-second? At least I do. So in general you can do something like this:

[SWF(frameRate='1000',width='800',height='600',backgroundColor='0xCCCCCC')]

This results for me in a constant framerate of 250. It seems to me that there is a limit that Flash puts on the framerate. But 250 is lame to me. Why not go for the 1000? It was a lucky find because I used stage.frameRate = 25; at one point and then wanted to switch back to 1000. But the result was not a constant framerate of 250 but… 976. Seems to me that Flash is not using a limit at this point. Sweet :o)

Update:
You can try using [SWF(frameRate='1000')] and -default-frame-rate 1000 as a compiler argument. Both will result in the same if you do trace( stage.frameRate ). The maximum that you can set is 0xff so Adobe is using a byte here. But inside the Flash player you are allowed to use more than a byte.

Creating an interface based event system

While programming an own event system for a user-interface I came up with nice way that handels all events based on interfaces. The good thing about this is that a window or UI object like a button is only typed as an interface and automatically registered to an event dispatcher.

First of all why not use the built-in event system? The reason to develop an own system was that Flash is very overdosed if you are creating a complex application that uses drag & drop, multiple windows and so on. There are a lot of references that you would have to use, a lot of listeners you would have to add and of course to remove because of the garbage collection.

Why not use the components? Personally I do not like the whole components architecture. They are also not fast enough for my purpose. And I do not want to include a 200kb swc if you think about bandwidth optimization. Maybe there is a way to include not the whole swc but as far as I do not want to use the Flex components anyway here is my solution.

The interface idea:
Every object you want to register to the event dispatcher needs only an interface. So for instance if I create a button I only use
[as]public class Button extends Bitmap implements IClickable[/as]

The button is now automatically registered to the event system. The event system is doing the following (pseudocode):

[code]event dispatcher on click
{

objects = stage.getObjectsUnderPoint( mouse );

loop through objects from top to bottom
{
if ( object is IHitable )
{
if ( object.isHit( mouse ) )
{
if ( object is IClickable )
{
object.onClick();
}

stop loop because there was an intersection
}
}
}
}[/code]

There is one base interface that every interface has to extend because you want to be able to check if there was an intersection or not. This interface is IHitable. Now I am able to do the same for nearly all interfaces. If a window shoule be dragable I just have to create an interface for a dragable window which is handled inside the event dispatcher that is also able to move the window. So it is more than only a event dispatcher but more a UI manager. The window implements only the interface and does not have to care about focus, movement or whatever.

The power and problems of DisplayObject.getObjectsUnderPoint():
The function DisplayObject.getObjectsUnderPoint() returns an array of objects that are currently under a given point. If you have a button on a window it would return something like [ Window, Button ]. Now the problem is that your button could be a Sprite and you added some Bitmap object onto it (because you can not use the handcursor with a Bitmap). So the function returns [ Window, Bitmap ] in this case but you implemented the interface for the button not for the Bitmap. The way to get arround this problem is walking the displaylist upwards until you hit the interface you are searching for.

The whole system seems to work pretty well and is also very fast. The idea of using interfaces to regiser your class to an event system is nice because you do not have to care about a lot of stuff. Registering your object to the event dispatcher is done by creating it and removing it from the dispatcher is done by removing it.

Closing in Flash

Working with images in Flash leads to some simple problems. First of all you have the general performance issues and then no possibilities of working with binary images and fast morphological filters. This makes it really hard to approach good results. For example: The background subtraction experiment works with a basic scene subtraction technique.

Some time ago I have done some “research” (German article) and created all programs in C++. The scene subtraction was very good and I had no holes in the extracted objects. Just because I was able use a three-dimensional color space and also grayscale and binary immages together.

What makes a binary image so important? Of course most color information will be lost. What you still have is the shape of an object. You can apply a lot of filters to a binary image and they are very fast since you only got {0;1} instead of {0;…;255} values per channel. A very powerful group of filters are the morphological filters. They are based on the shape of an object and gain information or modify that shape.

Now back to topic. The closing filter. It is a filter that allows you close holes in an image. If you do some background subtraction you will always have some holes inside your image (if you do not use a special light setup). So what do we need? A fast and working closing filter.
Continue reading ‘Closing in Flash’




Close
E-mail It