Some notes on inheritance in ActionScript 2

When implementing super and subclasses, Flash will call the superclass’ constructor automatically unless you call it yourself.
Imagine you have the following code:

class Super { 
   public function Super () {
       trace ("super called");
   }
}

class Sub extends Super { 
}

var myObject:Object = new Sub();

Read more

Inverting the alpha of a bitmap image in ActionScript 2

A piece of code and a demo says more than a thousand words :). This code demonstrates inversion of an alpha channel in Flash8/AS2.


/**
 * This example demonstrates inverting an alpha channel on an image.
 * Since Flash premultiplies the alpha, we need to keep two separate images: one with the color data, and 
 * one with the alpha data.  It demonstrates splitting the alpha from an image, inverting and proves 
 * premultiplying the alpha destroys color information.
 *
 * @author J.C. Wichman / Objectpainters.com
 */

import flash.geom.Rectangle;
import flash.geom.Point;
import flash.display.BitmapData;
import flash.filters.ColorMatrixFilter;

//set up some default params for the images
var width:Number = 100;
var height:Number = 100;
var fillColor:Number = 0x000000;

/**
 * Simple function that checks how many bitmaps have already been shown on stage and
 * bases the location for the next one on that information. Never use code like this
 * out of context, since its bad programming practice:).
 */
function showBitmap (pBitmap:BitmapData, title:String) {
	var imageCount:Number = this.getNextHighestDepth();
	var row:Number = Math.floor (imageCount/3);
	var columns:Number = imageCount%3;

	var newClip:MovieClip = this.createEmptyMovieClip("image"+imageCount, imageCount);
	newClip.attachBitmap(pBitmap, 0);
	newClip.createTextField("title", 1, 0, 110, 10,10);
	var textClip:TextField = newClip["title"];
	textClip.autoSize = true;
	textClip.text = "Image "+imageCount+":\n"+title;
	var tf:TextFormat = new TextFormat();
	tf.font = "Arial";
	tf.align ="center";
	textClip.setTextFormat(tf);
	
	newClip._x = (columns * 150)+10;
	newClip._y = (row * 170)+10;
}


//setting up demo rgb image, this is an image without alpha. 
//Since flash uses premultiplied alpha, adding an alpha channel will ruin the image for
//further use when we want to invert the alpha channel, so we keep colours separate from alpha
//(omg pink shirts!)
var colorImage:BitmapData = new BitmapData(width, height, false, fillColor);
for (var x = 0; x < width; x++) {
	for (var y = 0; y < height; y++) {
		//fiddle with the pixel data to show a dark gradient
		colorImage.setPixel( x,y, x<<16|y<<8|x+y);
	}
}
showBitmap (colorImage, "Colour w/o alpha");

//now we create a demo alpha bitmap. All color info is non existent, only
//alpha data is set. When x<y the alpha value is near opaque, otherwise its near transparent.
//we only use 0xAF and 0x10 instead of 0xFF and 0x00 to show partial alpha values are inverted ok as well
var demoAlpha:BitmapData = new BitmapData(width, height, true, fillColor);
for (var x = 0; x < width; x++) {
	for (var y = 0; y < height; y++) {
		demoAlpha.setPixel32( x,y, (x<y?0xAF:0x10)<<24);
	}
}
showBitmap (demoAlpha, "Alpha only");

//now imagine you didnt have a separate alpha bitmap to start with, but a starting image with alpha
//which you needed to extract first:
var alphaSplit:BitmapData = new BitmapData(width, height, true, fillColor);
//copy the alpha channel of one image to another image
alphaSplit.copyChannel(demoAlpha, new Rectangle(0,0, width, height), new Point(0,0), 8,8);
showBitmap (alphaSplit, "Alpha channel copy\n (same as previous)");

//now we are going to invert the alpha. This can be done on a pixel by pixel basis, but this might just
//be faster, you'd have to test it
var alphaInvert:BitmapData = alphaSplit.clone();
var matrix:Array = new Array();
matrix = matrix.concat([1, 0, 0, 0, 0]); // red
matrix = matrix.concat([0, 1, 0, 0, 0]); // green
matrix = matrix.concat([0, 0, 1, 0, 0]); // blue
matrix = matrix.concat([0, 0, 0, -1, 0xff]); // alpha, negate the alpha and add 255
alphaInvert.applyFilter(alphaInvert, alphaInvert.rectangle, new Point(0, 0), new ColorMatrixFilter (matrix));
showBitmap (alphaInvert, "Inversion of \nalpha channel");

//now the real action, we combine our original color pixels with the inverted alpha channel
var comboImage:BitmapData = new BitmapData(width, height, true, fillColor);
comboImage.copyPixels(colorImage, colorImage.rectangle, new Point(0,0), alphaInvert, new Point(0,0));  
showBitmap (comboImage, "Colours + \ninverted alpha");

//now to prove premultiplied alpha destroys color information:
var colorImgWithAlpha:BitmapData = new BitmapData(width, height, true, fillColor);
for (var x = 0; x < width; x++) {
	for (var y = 0; y < height; y++) {
		//fiddle with the pixel data to show a dark gradient
		colorImgWithAlpha.setPixel32( x,y, (x<y?0xfe:0x01)<<24|x<<16|y<<8|x+y);
	}
}
colorImgWithAlpha.applyFilter(colorImgWithAlpha, colorImgWithAlpha.rectangle, new Point(0, 0), new ColorMatrixFilter (matrix));
showBitmap (colorImgWithAlpha, "Colour with\n premultiplied \n inverted alpha");

Casting to Array in ActionScript 2

Imagine you have:
var my2dArray:Array = new Array();

my2dArray.push ([1,2,3,4,5]);
my2dArray.push ([6,7,8,9,0]);

And now you want to access and cast an element of myArray to an array:

var firstArray:Array = Array (my2dArray[0]);
trace (firstArray.length);

Right?
Read more

Create your own testserver with a fake domain (XP)

When you are developing a theme for say Joomla, or editing a lot of content, it is easier now and then to do this offline.
However if you DO want to do this offline, you’ll need a testserver.

I’ve been using JSAS, Joomla StandAlone Server for that purpose (but switched to XAMPP recently).

Once installed, you’re good to go with apache, php, mysql and joomla.

By default it will give you a local webserver on your localhost, reachable on port 85, in other words, to test it, goto :
http://localhost:85/

Inside the JSAS directory you will find a http_root directory, with a www directory inside it, and that’s the directory that will show in your browser by default if you go to http://localhost:85/.

Now imagine you have a site www.mybogussite.com and a www.myothersite.com and you both want to test/develop these offline.
You probably end up with something like:
http_root/www/mybogussite
http_root/www/myothersite

or

http_root/www/www.mybogussite.com
http_root/www/www.myothersite.com

BUT since you have to access them through links such as localhost:85/myothersite/ links might be broken.

One other way to handle this is by using virtual hosts.
Read more

Commandline scripting in PHP 5

At TriMM I am working on an eLearning environment consisting of a core engine and some 500 swfs (and growing). Some of these locations are very simple, like an image with hotspots and some are more complex such as an emailclient. The engine is refactored now and then, and extended, in addition the requests for some of the locations themselves might change.
All the work is done by different people in different roles, and some location versions might or might not be compatible with certain version of the core engine.

Why am I telling you this? Because I switched from Flash to PHP because of this? 🙂 No way.

But I do have to write a script to automate the release process, which will collect the latest versions of all location swf’s that go with a certain core engine version. I thought about using Ruby or Python for that, but since TriMM does a lot of Java, PHP and Flash, I decided it had to be one of those 3.

My first choice was PHP since it is a scripting language and doesn’t have to be compiled. Having written a little bit in it, I’m not so sure if I’m gonna stick with my choice since me and untyped functional languages dont really match, but okay okay I’ll try.
Read more

Wrapping function calls in ActionScript 2

Also known as:

  • debugging function calls
  • displaying the name of a called function
  • tracing function calls director like

Today I finally got to try something I had been wanting to try for a long time: wrapping function calls in a nice way.

I had been playing around with function pointers etc, which was ok in itself, but I was forced to create the messy pointer bit each time over again. So I implemented a FunctionWrapper class.

Say we have a class Test, with a method testMethod.

Now we want to execute some code before calling testMethod and after calling testMethod. “Well write another function to do so”, you might say. Of course that is one option, but assume we are looking for another way to do so (I’ll discuss some scenario’s in a minute).
Read more

Local Flash Content and SSL

We are in the process of migrating one of our largest eLearning systems to SSL and Active Directory. Some of the Learning Objects within this system are pretty complex and I’ve implemented a mechanism which allows you to test them standalone.

However during the migration to SSL these objects stopped working when run locally, from the IDE or from FlashDevelop.

I tried to wrap my head around why this was happening, since I’ve been doing less and less with serverside content and certificates these past few years.

Luckily I found this URL which described the problem quite accurate.

Http:// content cannot always access https:// content it seems, but the invalid security certificate was the biggest issue for us.

Our system admin Roy Olthof quickly jumped in, installed a valid certificate and tadaaaaa. Local content could access https content again. Note that we were accessing https content on our own test server, which didnt have a certificate installed.

In addition the Flash content kept giving me the mixed content (secure and unsecure) warning. After changing all the http://’s in the macromedia/adobe codebases (contained within the object and embed tags) this disappeared as well.

Drawing using controlpoints

There is an old trick which comes down to drawing a fluid line through controlpoints, by using the average of the controlpoints as anchors.

Here is my quick and dirty go at it:



You can download the example here: [Download not found]

arguments.callee._name in ActionScript 2

A question on the flashcoders list about an hour ago triggered me to put together a very simple example that I have been wanting to put together for ages now.

How do you get the name of a function?

With function we could refer to:

  • any function
  • a calling function
  • a function being called

My reflection package is at the core of my xflas2 logger. It provides much the same information MTASC can put into a trace statement WITHOUT MTASC (except for the linenumbers).

Anyway, the reflection package is perfectly capable of being used standalone without a logger of some kind. It provides two simple classes with an even simpler API: ClassFinder and FunctionFinder.

Imagine a function:

	
	private static function runExample3() {
		_print (
			"I am :"+
			FunctionFinder.getFunctionName(arguments.callee)+
			" and I am defined in "+
			ClassFinder.getClassName(
				FunctionFinder.getFunctionClass(arguments.callee)
			)+
			" and was called by "+
			FunctionFinder.getFunctionName(arguments.caller)				
		);
	}

Note that it’s static, but it doesn’t have to be, I’m just being a lazy git.

This prints:


I am :runExample3 and I am defined in SampleClass and I was called by main

Now, for the small print : you HAVE to call ClassFinder.registerAll() once somewhere at the start of your program.

Download the sample here: [Download not found]

AsSetPropFlags Explained

You might stop reading here, everything you need to know is in the provided example:[Download not found].

So you have decided to read on. Yes, it’s 2007 & I’m still doing AS2. I know, it’s sad, and I’m never gonna get my band started (weird purple tentacle sucking noises). But believe or not, I still love it :).
One of the things on my todo list was understanding the AsSetPropsFlags demon. As with all things, once you do understand them, you can’t understand why it took you so long.

AsSetPropFlags is simple. Really. Assuming you know your binary numbers, and I assume you do. But if you don’t check the example below and the utility classes provided.

So now I’m going to try and explain it to you :). Note that I only have used it in Flash 7 and above, so don’t ask me about all the flash 5 and flash 6 weirdness involved.

Read more