Latest snippets

Skew DisplayObject

var box:Shape = Shape(addChild(new Shape()));
with (box.graphics) beginFill(0x006666), drawRect(0,0,50,50);
box.x = box.y = 100;

addEventListener(Event.ENTER_FRAME, onLoop);

function onLoop(evt:Event):void {
	
	var m:Matrix = box.transform.matrix;
	// skew on the X
	m.c = (mouseX - stage.stageWidth / 2 ) / stage.stageWidth;
	
	// skew on the Y
	// m.b = (mouseX - stage.stageWidth / 2 ) / stage.stageWidth 
	
	box.transform.matrix = m
}

This skews a box Shape using the c and b properties of the transformation matrix. Note that these values don’t match those in the IDE’s transform window. This is good further reading if your interested in this topic.

Basic Tint Function

// display object, red (0-255), green, blue, amount (0-1)
function tint(dsp:DisplayObject, r:Number, g:Number, b:Number, amount:Number=1):void {
	if (amount != 1) {
		r *= amount;
		g *= amount;
		b *= amount;
	}
	amount = 1-amount;
	var ct:ColorTransform = transform.colorTransform;
	ct.redOffset = r;
	ct.redMultiplier = amount;
	ct.greenOffset = g;
	ct.greenMultiplier = amount;
	ct.blueOffset = b;
	ct.blueMultiplier = amount;
	dsp.transform.colorTransform = ct;
}

// test out the tint function on a circle with a stroke:
var circle:Shape = Shape(addChild(new Shape()));
with (circle.graphics) {
	lineStyle(5, 0x339999);
	beginFill(0x003333);
	drawCircle(0,0,50);
	x = 100;
	y = 100;
}

// tint the circle 50% green
tint(circle, 0, 255, 0, .5);

The ColorTransform object is a little confusing with its “redMultiplier, redOffset, greenMultiplier etc…” properties. Once you understand them it’s not a big deal, but I still find them a bit cumbersome. So when I just want to tint a clip similar to the way you might tint a clip in the IDE… I use this tint function. Rather than taking a hexidecimal number it takes values for red, green and blue (0-255) – and an amount argument (0-1).

Mouse Velocity

var velocityInfo:TextField = new TextField();
velocityInfo.x = 20;
velocityInfo.y = 20;
addChild(velocityInfo);

var prevX:Number = mouseX;
var prevY:Number = mouseY;
var velX:Number = 0;
var velY:Number = 0;

addEventListener(Event.ENTER_FRAME, onLoop);

function onLoop(evt:Event):void {
	 
	 velX = mouseX - prevX;
	 velY = mouseY - prevY;
	 
	 velocityInfo.text = velX + ", " + velY
	 
	 prevX = mouseX;
	 prevY = mouseY;
}

Wrote this in response to a question from one of my students. The next step is to use velX and velY to push objects around the screen.

Animate Along a Path

stage.frameRate = 30;
var pencil:Shape = new Shape();
addChild(pencil);

var index:int = 0;
var points:Array = new Array();
var circle:Shape = new Shape();
circle.graphics.beginFill(0x000000);
circle.graphics.drawCircle(0,0, 5);
addChild(circle);

stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);

circle.addEventListener(Event.ENTER_FRAME, onMoveCircle);

function onDown(evt:MouseEvent):void {
	pencil.graphics.lineStyle(0,0x000000);
	pencil.graphics.moveTo(mouseX, mouseY);
	stage.addEventListener(MouseEvent.MOUSE_MOVE, onDraw);
}

function onUp(evt:MouseEvent):void {
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDraw);
}

function onDraw(evt:Event):void {
	pencil.graphics.lineTo(mouseX, mouseY);
	points.push(new Point(mouseX, mouseY));
}

function onMoveCircle(evt:Event):void {
	if (points.length>0) {
		circle.x += (points[index].x - circle.x) / 4;
		circle.y += (points[index].y - circle.y) / 4;
		index++;
		if (index==points.length) {
			index=0;
		}
	}
}

Wrote this in response to a student question. It causes a circle shape to animate along lines drawn by the user.

new Sprite() One-liner

var s:Sprite = Sprite(addChild(new Sprite()));

A way to make a new sprite, add it to the display list and store a reference to it.

Figured this out on my own… but have since seen it around on a few flash blogs here and there… thought it deserved a post.

Alphabet with Base36 and Binary

var canvas:BitmapData=new BitmapData(280,100,false,0xefefef);
addChild(new Bitmap(canvas));

// pixel alphbet in base36
var alphabet:Array=["", "67erkgi", "e3j6dss", "75rue4u", "c5ltok8", "75s2tji", "75s2tjk", "75rugj2", "95yfnf6", "21blls4", "10nt5xo", "973it1u", "85aef4u", "59lu6nl", "cnz0hbn", "67ej51o", "67eq49c", "67ej53e", "67eq7gy", "66978m4", "6ywdqpw", "95y780c", "53b00as", "8nmdpyi", "5374thm", "53avnus", "6xsfdam"];

function drawBase36(num:String, xp:int, yp:int):void {
	// convert base36 to binary
	num=parseInt(num,36).toString(2);
	while (num.length < 35) {
		num="0"+num;
	}
	// draw letter
	for (var i:int= 0; i<35; i++) {
		if (num.charAt(i)=="1") {
			canvas.setPixel(i % 5 + xp, int(i / 5) + yp, 0x000000);
		}
	}
}

// draw the entire alphabet
for (var i:int = 0; i<alphabet.length; i++) {
	drawBase36(alphabet[i], i * 10,10);
}

// draw some words
var words:Array=[0,1,3,20,9,15,14,19,14,9,16,16,5,20,0,9,19,0,3,15,4,5];
for (i = 0; i<words.length; i++) {
	drawBase36(alphabet[words[i]], i * 10,30);
}

I had lots of fun writing this. If you run it in your timeline it will draw this:


… along with the message stored in this array [0,1,3,20,9,15,14,19,14,9,16,16,5,20,0,9,19,0,3,15,4,5].

Binary can be used for representing small images. For every 0 draw white for every 1 draw black. So when the base36 numbers are converted to binary, the 1’s and 0’s are used to draw each letter.

An interesting side note is that counting in binary to some very high numbers will enumerate all possible two color images at a given size. There are tons of projects related to this… here is one I found with a quick google search: every icon

I also found the wikipedia entry on base36 to be interesting. Apparently base36 can be called hexatridecimal, sexatrigesimal, hexatrigesimal or alphadecimal.

2D Z-Sort

var shapes:Array = new Array();

for (var i:int = 0; i<300; i++){
	var s:Shape = new Shape();
	s.x = Math.random()* stage.stageWidth;
	s.y = Math.random()* stage.stageHeight;
	s.graphics.lineStyle(0,0x000000);
	s.graphics.beginFill(0xCCCCCC);
	s.graphics.drawCircle(0,0, Math.random()*s.y / 5);
	shapes.push(s);
}

// comment this out to remove sorting
shapes.sortOn("width", Array.NUMERIC);

for (i = 0; i<shapes.length; i++){
	addChild(shapes[i]);
}

This uses Array.sortOn() to do some basic z-sorting based on the width property of some circle shapes.

Set Multiple Properties

// set multiple properties of an Object 
function setProps(o:*, props:Object):void{
	for (var key:String in props){
		 o[key] = props[key];
	}
}

// example: 

var s:Sprite = new Sprite();
s.graphics.beginFill(0);
s.graphics.drawRect(0,0,10,10);
addChild(s);

// set some properties
setProps(s, {x:100, y:100, scaleX:2, scaleY:2, rotation:45});

This was inspired by tweening engines like TweenLite.

Basically the same thing using a with statement:

with(s) x = 100, y = 100, scaleX = 2, scaleY = 2, rotation = 45;

10,000 35 ways, .toString(radix);

for(var i:int = 2; i<37; i++){
	trace((10000).toString(i));
}
/*
outputs:
10011100010000
111201101
2130100
310000
114144
41104
23420
14641
10000
7571
5954
4723
3904
2e6a
2710
20a4
1cfa
18d6
1500
11e4
kec
iki
h8g
g00
ekg
dja
cl4
bpo
b3a
aci
9og
961
8m4
85p
7ps
*/

I had either totally forgotten about or never known about the Number, uint, int etc… .toString() radix argument. Brock mentioned it to me in conversation and I’ve been having fun with it ever since. It’s especially nice for tracing out hex numbers:

var red:Number = 0xFF0000;
trace("decimal:");
trace(red);
trace("hex:");
trace(red.toString(16));

Mini Tween Engine

var box:MovieClip = new MovieClip();
box.graphics.beginFill(0xFF0000);
box.graphics.drawRect(-25,-25,50,50);
addChild(box);

stage.addEventListener(MouseEvent.CLICK, onStageDown);
function onStageDown(evt:MouseEvent):void{
	moveTo(box, "x", 300, 2, Back.easeOut);
	moveTo(box, "y", 200, 2, Back.easeOut);
	moveTo(box, "scaleX", 2, 2, Back.easeOut);
	moveTo(box, "rotation", 180, 2, Quartic.easeOut, onDone);
	stage.removeEventListener(MouseEvent.CLICK, onStageDown);
}
					 
function onDone():void {
	moveTo(box, "x", 120, 2, Back.easeIn);
}

//
// -- TWEEN ENGINE
//
import fl.motion.easing.*;

// movieClip to tween, property to tween, final value for the property, duration of tween,
// ease type, complete callback function
function moveTo(mc:MovieClip, prop:String, dest:Number, duration:Number, ease=null, 
				           completeFunction:Function=null):void {
	if (ease == null) {
		ease = Quartic.easeOut;
	}
	// use the property to make all var names unique
	mc["begin" + prop] = mc[prop];
	mc["change" + prop] =  dest - mc[prop];
	mc["time" + prop] = 0;
	mc["startTime" + prop] = getTimer();
	mc["duration" + prop] = duration;
	mc["prop"] = prop;
	mc["ease" + prop] = ease;
	mc["complete_" + prop] = completeFunction;
	mc.addEventListener(Event.ENTER_FRAME, makeMotionFunction(mc, prop));
}

function makeMotionFunction(mc:MovieClip, prop:String):Function {
	return function(evt:Event){
		if (mc["time" +prop] <= mc["duration"+ prop]){ 
		   mc[prop]=mc["ease" + prop](mc["time" + prop], mc["begin" +prop], mc["change"+ prop], mc["duration"+ prop]);
		} else {
			var completeFunction:Function = mc["complete_"+prop];
			if (completeFunction!=null){
			  completeFunction();
			}
			mc.removeEventListener(Event.ENTER_FRAME, arguments.callee);
			// see how long the tween took
		    //trace(mc["time"+prop]);
		}
		   mc["time" + prop] = (getTimer() - mc["startTime" + prop]) / 1000;
	};
}
/*
WARNING: This code was written for fun. Use at your own risk.
*/

This code uses a ~35 line tweening engine. I wrote this for fun a few weeks back. It works by creating dynamic variables on the MovieClip that it tweens. The dynamic variables and the square bracket syntax cause it to be pretty slow. Definitely not a substitute for a real tweening engine… like TweenLite.

I wouldn’t recommend using this for anything other than playing around. See warning page for more info.