Latest snippets

String.replace()

var words:String = "ActionSnippet.com is a website. ActionSnippet.com is a blog.";

// outputs: "ActionSnippet.com is a website. ActionSnippet.com is a blog.";
trace(words);

// the "/g" tells it to replace all instances of ActionSnippet.com
words = words.replace(/ActionSnippet.com/g, "SomeWebsite.com");

// outputs: SomeWebsite.com is a website. SomeWebsite.com is a blog.
trace(words);

Just a quick response to a student question.

Recursive Tree

var branches:int = 0;
var maxBranches:int = 400;
 
graphics.lineStyle(0,0x000000);

makeBranch(300,350,100,-45,45);
	 
function makeBranch(xp:Number, yp:Number, leng:Number, min:Number, max:Number):void {

	var endX:Number, endY:Number;
	var theta:Number = (min + Math.random()*(max-min) - 90) * Math.PI / 180;
	 
	endX = xp + leng * Math.cos(theta);
	endY = yp + leng * Math.sin(theta);

	graphics.moveTo(xp, yp);
	graphics.lineTo(endX, endY);
	
	if (branches < maxBranches) {
		var newLength:Number = leng*.7; 
		setTimeout(makeBranch, 0, endX, endY, newLength, -90, 0);
		setTimeout(makeBranch, 0, endX, endY, newLength, 0, 90);
	}
	branches+=2;
}

Draws a tree using recursion.

3D Shape

stage.frameRate = 30;
var centerX:Number = 200, centerY:Number = 200, zpos:Number, xpos:Number, ypos:Number, depth:Number;
var rotX:Number = 0, rotY:Number = 0, px:Number, py:Number, pz:Number;
var cosx:Number, cosy:Number, sinx:Number, siny:Number;

var canvas:BitmapData = new BitmapData(400,400,true,0xFF000000);
addChild(new Bitmap(canvas));
 
addEventListener(Event.ENTER_FRAME, onLoop);
 
function onLoop(evt:Event):void {
	canvas.fillRect(canvas.rect, 0xFF000000);
	 rotX += (mouseX / 50 - rotX)/12;
	 rotY += (mouseY / 50 - rotY)/12;
	 
	 cosx = Math.cos(rotX);
	 cosy = Math.cos(rotY);
	 sinx = Math.sin(rotX);
	 siny = Math.sin(rotY);
	 for (var a:Number =0; a < 6.28; a+=.1){
		  for (var b:Number =0; b < 6.28; b+=.05){
			  px = 100 * Math.cos(a) * Math.cos(b) * Math.cos(b);
			  py = 100 * Math.sin(a) * Math.cos(b) 
			  pz = 100 * Math.sin(b);
			  zpos= pz*cosx - px*sinx  ;
	          xpos= pz*sinx +px*cosx  ;
	          ypos= py*cosy - zpos*siny  ;
	          zpos= py*siny+ zpos*cosy ;
			  depth = 1/((zpos/340)+1);
			  canvas.setPixel((xpos * depth) + centerX, (ypos * depth) + centerY, 0xFFFFFF);
		  }
	 }
}

Renders a rotating 3D shape.

Simple Particles

stage.frameRate = 30;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void{
	if (int(Math.random()*5)==1){
	  for (var i:int= 0; i<10; i++) createParticle();
	}
}

function createParticle():void{
	var s:MovieClip = new MovieClip();
	s.graphics.beginFill(0);
	s.graphics.drawCircle(0,0,Math.random()*10 + 2);
	s.velX = Math.random()*10-5
	s.velY =  Math.random()*10-5
	s.posX = s.x = 200;
	s.posY = s.y = 200;
	addChild(s);
	s.addEventListener(Event.ENTER_FRAME, onRunParticle);
}

function onRunParticle(evt:Event):void {
	var s:MovieClip = MovieClip(evt.currentTarget);
	s.posX += s.velX;
	s.posY += s.velY;
    s.scaleX = s.scaleY -=  .04;
	if (s.scaleX < 0){
		removeChild(s);
		s.removeEventListener(Event.ENTER_FRAME, onRunParticle);
	}
	s.x = s.posX;
	s.y = s.posY;
}

Nothing special here. But my students are always asking me about this – in class I have them alter this code to make fire, water and abstract particle systems.

Dynamic Timeline Vars

this.myVar = "I am a dynamic variable";
trace(this.myVar);

// trace(myVar) // will cause an error

This code will add dynamic untyped variables to the timeline. Although this example is pretty useless, it scratches the surface of an interesting topic…. by default all flash timeline code gets compiled into a giant dynamic document class that uses the undocumented addFrameScript() function. This means that all import statements on the timeline, even ones not on frame one become part of this large document class.

Recursion Trick w/ setTimeout()

var counter:int = 0;

graphics.lineStyle(0,0x000000);

recursive();

function recursive():void{
	
	if (counter < 4000){
	   graphics.moveTo(10,10);
	   graphics.lineTo(counter, 200);
	   counter+=4;
          // don't call recursive(), use setTimeout instead
	   setTimeout(recursive,0);
	}else{
		trace(counter / 4 + " lines were drawn");
	}

Be careful with this one, if you don’t know what your doing you may be able to crash flash.

Anyway… if you use a recursive function in flash you may find yourself getting a stack overflow error. You can avoid this by using setTimeout():

 // don't call recursive(), use setTimeout() instead
setTimeout(recursive,0);

Of course… the stack overflow error is there for a reason, if used incorrectly you could bring the flash player to a standstill.

You can also achieve animated recursion by actually adding a delay to your setTimout() call:

 // don't call recursive(), use setTimeout() instead
setTimeout(recursive,10);

MovieClip.prototype

MovieClip.prototype.tint = function(col:uint):void {
	var ct:ColorTransform = transform.colorTransform;
	ct.color = col;
	this.transform.colorTransform = ct;
}

var circle:MovieClip = MovieClip(addChild(new MovieClip()));
with (circle.graphics) {
	beginFill(0x123455);
	drawCircle(0,0,50);
	x = 100;
	y = 100;
}

circle.tint(0xFF0000);

When AS3 first came out I didn’t realize that prototype was still around…. This adds a function called tint() to all MovieClips. You should extend MovieClip instead of using this method…. but it’s interesting to see that it’s still around. There’s an explanation of prototype and the AS3 namespace here.

10,000 Transparent Sprites

stage.frameRate = 30;

var imageNum:int = 10000;
var point:Point = new Point(0,0);
var s:Sprite = new Sprite();
s.graphics.beginFill(0xCCCCCC);
s.graphics.lineStyle(0,0x000000);
s.graphics.drawCircle(3,3,3);
s.alpha = .1;

var nested:Sprite = new Sprite();
nested.addChild(s);
var image:BitmapData = new BitmapData(s.width, s.height, true, 0x00000000);
image.draw(nested);

var canvas:BitmapData = new BitmapData(400,400, true, 0xFFFFFFFF);
addChild(new Bitmap(canvas));

var xPos:Array = new Array();
var yPos:Array = new Array();
for (var i:int = 0; i<imageNum; i++) {
	xPos.push(Math.random()*400);
	yPos.push(Math.random()*400);
}

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.fillRect(new Rectangle(0,0,400,400), 0xFFFFFFFF);
	var div:Number;
	for (var i:int = 0; i<imageNum; i++) {
		div  = (i / 100)+2;
		xPos[i] += (mouseX - xPos[i])/div;
		yPos[i] += (mouseY - yPos[i])/div;
		point.x = xPos[i];
		point.y = yPos[i];
		canvas.copyPixels(image, image.rect, point, null, null, true);
	}
}

This is from my other blog but I figured it was worth posting here. It draws 10’000 transparent circles that each follow the mouse at different speeds. This is achieved using copyPixels().

Loader, Centering, Smoothing

var image:Loader = new Loader();
image.load(new URLRequest("http://www.shapevent.com/sketchbook/wp-content/uploads/avalanche.jpg"));
image.x = stage.stageWidth / 2;
image.y = stage.stageHeight / 2;
addChild(image);

image.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onComplete(evt:Event):void {
	
	// CENTER THE IMAGE
	image.content.x = -image.content.width / 2;
	image.content.y = -image.content.height / 2;
	
	// BITMAP SMOOTHING
	Bitmap(image.content).smoothing = true;
	image.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
}


// scale the image with the mouse to demonstrate smoothing and scaling from the center
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	image.scaleX = image.scaleY = mouseX / stage.stageWidth;
}

This is really two snippets combined. How to scale the content of a Loader from the center:

// CENTER THE IMAGE
image.content.x = -image.content.width / 2;
image.content.y = -image.content.height / 2;

and how to smooth a jpg, png etc… that has been loaded dynamically into your swf:

// BITMAP SMOOTHING
Bitmap(image.content).smoothing = true;

Reset Registration Point


// display object target, value - "center" or "upperLeft"
function setRegistration(dsp:DisplayObjectContainer, v:String):void {
	var i:int;
	var child:DisplayObject;
	var b:Rectangle=getBounds(dsp);
	for (i = 0; i < dsp.numChildren; i++) {
		child=dsp.getChildAt(i);
		child.x+=b.x*-1;
		child.y+=b.y*-1;
	}
	if (v=="center") {
		dsp.x+=dsp.width/2;
		dsp.y+=dsp.height/2;
		for (i = 0; i < dsp.numChildren; i++) {
			child=dsp.getChildAt(i);
			child.x-=dsp.width/2;
			child.y-=dsp.height/2;
		}
	} else if (v == "upperLeft") {
		if (dsp.parent) {
			b=getBounds(dsp.parent);
			dsp.x=b.left;
			dsp.y=b.top;
		}
	}
}

// example:
// (make a MovieClip and fill it with, text, shapes etc...)

setRegistration(clip, "center");
// registration(clip, "upperLeft");

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	clip.rotation+=1;
}

Teaching beginner flash… I’ve noticed people always get confused about the registration point. They think they should be able to move it with the IDE or ActionScript. I always say “You can’t change the registration point, you can only change the position of graphical elements in relationship to it.” Anyway, as a sort of joke one day after class I wrote the above function… it changes the registration of any DisplayObjectContainer to either “center” or “upperLeft”.

To test this code out, fill a MovieClip with a bunch of different things (text, graphics, scribbles)… give it a strange registration point and then run the above code on it. You’ll be able to tell that the registration has changed by the way the clip rotates. Although I haven’t been able to break this function, I think it’s possible that it doesn’t work under all circumstances.

Using reparenting is a more elegant solution to this issue. Maybe I’ll post that in the next couple days.