Archive for the 'workarounds' Category

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.

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.

ActionScript3 preprocessing

If you are familiar with C you know what a preprocessor is. Otherwise you may want to take a look at the blog of Mike Chambers and come back after reading his article on using a preprocessor with ActionScript.

If you read the article of Chambers or know about preprocessors in general you may know that you can not edit and compile the same file that you send through a preprocessor. Chambers does not have this problem because he uses a commandline everytime he compiles his files.

You could have one directory called \bin\ and one \source\ but that is very long-winded. What I need are the benefits of a preprocessor but I just do not want to feel that there is a preprocessor workin in the background.

Therefore I wrote two little applications. Let me explain how it works. My first idea was to substitute the MXMLC (aka Macromedia Flex Compiler). The problem is that the Compiler is deep integrated in the Flex framework and since I do not know anything about Eclipse and that framework stuff I had to throw that idea away.

The next solution that crossed my mind was to have two seperate applications. The first should create a backup of the code and then run the preprocessor. Then the Flex Builder could do his work. After that is done the second application should restore the original sourcecodes. Sounds good – works great.

How to?
First of all you need the cpp preprocessor that Chambers talks about. Google will be your friend. Then download my little package called as3pp. Now follow theese instructions:

Step 05
1.) Unzip to a location that fits into your aesthetic well-being.
2.) Start Flex Builder
3.) Create a new project
4.) Open Project->Properties and switch “Builders”
5.) Create a new Builder and call it “Preprocessor”. The settings should look like in the picture.
On the “Refresh” tab make sure that the following options are checked:
- Refresh resources upon completion.
- The selected source
- Recursively include sub-folders
On the “Build Options” tab make sure that the following options are checked:
- After a “Clean”
- During manual builds
- During auto bulds
- During a “Clean”
Done.
6.) Create another new builder and call it “File Restore”. The settings should be the same that you used for the preprocessor
7.) Arrange the builders in this order

You are done. Make sure to uncheck the “Build Automatically” option in the Project menu. You are done. The preprocessor works for me fine and I will never miss it anymore :o)

Please leave a comment about bugs etc. The as3pp tools should work with win9x/nt systems.

AS3 optimization

André Michelle released not just a very fast raycaster today but also made a very interesting post on the Flashforum. It is about the optimization of your AS3 code and I am in awe of his creative tests. The fastest method to fill an Array in AS2 was this one:

[as]var n: Number = 1000;
while ( –n > -1 )
array[ n ] = 0;[/as]

Now André just posted another method wich is a lot faster. The webcam with particles experiment moved from 25fps to 30fps.

This is what he posted and it describes the technique very well:

[as]var x: Number = 0;
while( x++ < 1000 )
{
// do something
}

var x: Number = 0;
while( x < 1000 )
{
x++;
// do something faster
}

// or inside conditions

if( ( z = iz * 100 ) < 0 )
{
// do something
}

z = iz * 100;

if( z < 0 )
{
// do something faster
}[/as]

How to use Sockets in Actionscript3?

After some kind of request it might be some time to explain detailed how I used the Socket in my IRC client. First of all I will explain how to bypass the securitymodel. I wrote about this before but I think it might be usefull to have it here again.

First of all Flash does not allow you to connect to servers that are outside the so-called sandbox of your Flash application. You are of course able to extend that sandbox by using Security.loadPolicyFile( ‘http://another-server/crossdomain.xml’ ); for example. Now most servers do not have such a file only for your pleasure.
The “simple” workaround here is using a proxy which is located on your server. A proxy is something that runs on your shell and is able to forward connections to other servers. Normally a connection goes direct from client to server (Client -> Server). Using a proxy would result in Client -> Proxy -> Server. Now the proxy is located on your server. That means every user that connects to some server would use your ip which is not good. Therefore I have to say this is not a satisfying workaround but at least you can connect to any server you want.
Proxys for IRC and other applications can be found at Google. An easy proxy is Proxy which is not hard to configure. For FTP applications I would suggest you using TLSWrap.

Now having the socket of your choice installed on your shell you are ready to go. IRC and many other protocols end every command with the CRLF. The binary representation of a CRLF is 13 10. I wrote some extended Socket for IRC but this might also be usefull for FTP. You can grab the sourcecode here. It is not very hard to understand. The sendString() method accepts a String which is different from the writeUTF8Bytes function of the socket. Most protocols do not like UTF-8 and so all the characters like äöü etc. would look scary on other clients. The sendString() function puts all characters into one ByteArray and terminates the string with a CRLF. After that the command will be send using writeBytes() and flush().

Now here is a short passage of code how I connect to other an IRC server. It is of course not the full application. I will release the whole thing when flIRC is finished and the code clean and smooth.

[as]
import flash.system.Security;
import flash.events.*;
import irc.*;

private var sock: IRCSocket;

private function main(): Void
{
Security.loadPolicyFile( ‘http://proxyhost/crossdomain.xml’ );
Security.allowDomain( ‘proxyhost’ );
Security.allowDomain( ‘proxyhost:port’ );

sock = new IRCSocket();
}

private function connect(): Void
{
if ( sock.connected )
{
sock.sendString( ‘QUIT :flIRC – http://blog.je2050.de/’ );
disconnect();
return;
}

registered = false;

// this is for dynamic connection
//sock.connect( host, uint( port ));

// we use a proxy
sock.connect( ‘proxyhost’, proxyport );

sock.onSockOpen = onSockOpen;
sock.onSockRead = onSockRead;
sock.onSockError = onSockError;
}

private function onSockOpen( event: Event ): Void
{
// … do the IRC logon process here
}

private function onSockError( event: Event )
{
// this is very simple for the moment
Alert.show( ‘Unknown socket error’, ‘Error’ );
}

private function onSockRead( input: String ): Void
{
if ( input == ” ) return;

// this is a simple way to get the informations you want
var tokens: Array = input.split( ‘ ‘ );

if ( tokens[ 0 ] == ‘PING’ )
{
// you are registered on an irc server after the first ping event
// registered = true;

// just show we got the event in the status window
//addStatusMessage( ‘Ping? Pong!’ );

// send the id back to the server
sock.sendString( ‘PONG ‘ + tokens[ 1 ] );
return;
}

// … handle all other events here
}
[/as]

I hope you get the idea. It is not very hard to establish a connection. I also hope this was interesting and usefull for you. Do not be shy and post a comment if I was not able to make this plain to you.

Links:

flIRC – First Steps in Flash 8.5 and Flex

THIS IS OUT OF DATE. CHECK THE NEWER VERSION HERE

flIRCI started working on my Flash IRC Client (flIRC) some time before Flash 8.5 was released. Now two days later I want to show you the first demo of my little project and experiment. You can see a very early version here.

Ther is still a lot of work to do but you can already join channels and talk. Private messages to other users are not supported yet like a lot of events like JOIN/PART/KICK/MODE etc. Please remember Flash 8.5 is now only two days old and I never used this Flex stuff before.

The application:
I am using Flex2. This is not an AS3 only project so I have got my code in theese mxml files which is a little bit confusing at the beginning but you will like it because you can be very fast. I do not care about application states, I do not care about initializing components and all this stuff. It is very easy to use. Even the alignment of the elements can be done by Flex.

Connection:
As I wrote one day ago there is a problem with the security model of Flash. The workaround is quiet simple and has nothing to do with Flash directly. I installed a proxy on my shell and just forward every connection to irc.quakenet.org. The only problem is that the connections are not client-side only.

Macromedia should handle a socket request like using the camera. A simple dialog box would make life easier.

Other problems:
The TextArea seems to be very buggy. I wont blame Macromedia for this because it is only an Alpha. But one problem is very annoying. If you use htmlText and add a lot of text very fast (while-loop for example) then the TextArea won’t display all the text you appended to it.
The workaround is using a simple flash.util.Timer and an Array where all messages get stored. On every tick one message gets added.

Most IRC clients do not support UTF-8 encoding. The socket got a writeUTFBytes() function but all the special german characters look wrong on other clients. The solution here was using a simple byte array which gets filled by a string. Most of the communication is now located in an own class called IRCSocket.

Using textarea.vPosition = textarea.maxVPosition; worked for me in Flash 8. This does not seem to work in 8.5 so currently the text wont scroll.

Links:

THIS IS OUT OF DATE. CHECK THE NEWER VERSION HERE

Fast pixel-scroller

With Flash8 you have got all that nice stuff. Since every release Macromedia anounces more performance. In most cases this is true, but just try the following code in Flash7 and Flash8

[as]var i: Number = 0;
var sum: Number = 0;
var sin: Function = Math.sin;
while ( i++ < 100000 ) sum += sin( i );[/as]

You won't get much differences in speed because Flash is way to slow to handle 100000 iterations. So if you want to do draw a 100x100px image by using something like this you won't have any chance of a good framerate (even if there are just 10000 iterations).

[as]var i: Number = 0;
var j: Number;
while ( i < 100 )
{
j = 0;
while ( j < 100 )
{
x.setPixel( i , j , calculateColor(i, j));
j++;
}
i++;
}[/as]

Of course you can see the 100x100 iterations here. You get the idea. Using loops to iterate through every pixel is not fast enough. This is and was slow since the release of Flash3. So where is all that performance they are talking about? Let's try to find out.

The best example in my eyes is a tilemap engine or so called pixel-scroller. Strille developed long time ago an object-based scroller. You can find it here and read about the technique here. The framerate of about 40fps (on my machine) was a huge step forward and very impressive. Now we have all that nice filters and BitmapData stuff and it should be possible to get more fps. Of course the filters won’t help us here.

The idea of a Flash8 pixel-scroller is very simple: Load all tiles and draw them into one big BitmapData. Then scroll only this one object instead of attaching, removing and repositioning tiles every frame.

The first thing you have to do is drawing all tiles into the BitmapData. This should not be to hard, because there is the function copyPixels() which makes it easy. But there is a very silly problem. The maximum size of a BitmapData object is 2880×2880px (I think). A simple map with 16×16px tilesize and a width of 200 tiles makes 16px * 200 = 3200px which is more than 2880px. What you have to do is to split the map up into several objects.

There is a simple workaround to solve this problem. Even if the maximum size of a BitmapData object is 2880×2880px the maximum size of a MovieClip is unknown to me. So what about splitting up the map into some BitmapData objects and draw all tiles by using copyPixels. Then using attachBitmap() to draw all bitmaps into MovieClips and putting them together. I have done this in two classes called BitmapComposer and TileComposer. What you see on the figure is the composition of all bitmaps and the pink rectangle is the viewport.

The last problem is the scrolling. How to scroll for example 4 very large MovieClips without losing performance? A simpls solution is using a mask. But do not forget we are using Flash8. And there is such a great feature which is called scrollRect. You just have to use the flash.geom.Rectangle to set which area is displayed. This makes scrolling very fast.

What are the problems of this method:

  • Your map is static – no animations
  • Tiles can not be removed or attached dynamicaly
  • It might be hard to understand how to split the map

But this is very great for background-scrollers. Imagine a game which is not tile-based but has got a scrolling background which is tile-based. I would recommend you to use this technique because the performance loss is to bear. Most games I have seen do not have any animated tiles. You could also combine this scroller with another one that is able to deal with animated and dynamically created tiles.

Maybe I will write another post about this because tomsamsom asked me to automate the composition part which is a bit wired. Just a simple explanation here:
[as]var comp: Array = [[[0,1],[0,1]],[[0,1],[1,2]],[[0,1],[2,3]]];
/*
[
[[0,1],[0,1]], // first bitmap. from y 0 to 1 and x 0 to 1
[[0,1],[1,2]], // second bitmap from y 0 to 1 and x 1 to 2
[[0,1],[2,3]] // third bitmap from y 0 to 1 and x 2 to 3
];
*/
var tilemap: BitmapComposer = new BitmapComposer(
mc, // mc to draw
320, // viewport width
240, // viewport height
comp, // composition array
map, // map array
flash.display.BitmapData.loadBitmap(“blocks”), // tiles
0×80, // tiles in x-direction per bitmap-object
0×20, // tiles in y-direction per bitmap-object
4 // tilesize is 1 << 4 = 16
);

tilemap.render( 100 , 100 ); // x and y
[/as]

Speeding up your glow effects

Look at all the glow effects Because of a current project I ran into some problems because I overused the GlowFilter. There are a lot of objects flying around that glow using blendMode add. You can imagine that the framerate directly decreased. Than I came up with four methods to create a glow effect I will list here.

Traditional way:
Create one empty movieclip and attach the object two times into that movieclip. The object with the lower depth has the glowfilter applied and the blendMode is set to add. The pros of this method are that it is very exact. The cons are of course the speed. Every frame needs a new calculation of the glow. This method should be used for objects where the glow accuracy is really necessary.

Cheap way:
Draw a simple shape of your object using radial blur for example. Create again one empty movieclip and attach the shape first, then the object. Now set the blendMode of the shape to add and you are done. This is very fast and cheap. It does not look very good but for some objects it makes sense. Imagine a ball for example or a planet in space.

Caching the glow:
This is a little bit more elegant. You start with an empty movieclip. Then create another empty movieclip and at last attach the object. Now you have to apply the GlowFilter to the object and draw that into a BitmapData. That can be attached to the other empty clip and the blendMode should be again set to add. Now you don’t have to draw the shape by yourself but of course if the object is animated it does not look very good because you will see that the glow has been cached for the first frame.

Simple code example:
[as]// imagine you have got the clip character
// another clip is character.characterMain
// and last but not least character.characterEffect
// —

// initialize filter
var glow: GlowFilter = new GlowFilter(0xFF99FF, 0×10, 0×10, 0×10, 0×01, 0×06, false, false );
characterMain.filters = [ glow ];

var matrix: Matrix = new Matrix();

// translate to correct position
matrix.translate( 40, 40 );

// correct size because of transition here
var bmp: BitmapData = new BitmapData( characterMain._width + 20, characterMain._height + 20, false, 0 );
bmp.draw( characterMain, matrix );

// attach bitmap and cache clip
characterEffect.attachBitmap( bmp, 1, ‘auto’, false );
characterEffect.cacheAsBitmap = true;

// sweet blend mode
characterEffect.blendMode = ‘add’;

// reset filters
delete characterMain.filters;[/as]

The last thing I can mention here is another method I never tried. You could cache every frame into a BitmapData. A thread in the FlashKit forums describes how to use BitmapData objects for animation. This should be the best way because it is fast and dynamic.