Actionscript 3 – Fun with 3D Particles

3D, actionscript 3, Math, morphing, Particles

Hi there, some time since I last posted a technical post so here we are.

Brief

I was experimenting with some simple 3d formulas and this is the result…
1200 particles morphing in 3D space.
Added an interactive camera to start having fun.

Usage

Simply move your mouse up/down to move camera forward/backward and left/right for strafing.
Perss SPACE bar to cycle particle conformation between four different shapes.

For better experience move forward and backward while particles are morphing…
Following the morph from behind while moving very fast feel very gratifing for me :)

Performances

On my old CPU it performs @31fps and neither takes the cpu at 100%
No z-sorting here, just fun. I am not trying to build a real 3d engine… and no class for now, just some procedural code, but I am sure my cool readers will not have problems wrapping it inside a class definition if needed. Also this site’s loading time is quite slow lately, to enhance it I might move into small business hosting in the future.

Caurina Tweener needed.

3dparticles.gif
Experience the demo

And here come the code! Simply past it in the first frame actions of a new fla.

import caurina.transitions.Tweener;
import com.oaxoa.components.FrameRater;
import flash.events.KeyboardEvent;

var particles:Array=[];
var particlesXY:Array=[];
var flen:Number=100;
var lines:Sprite=new Sprite();
var renderLines:Boolean=false;
var shapeN:int=-1;

var camera:Object={px:0, py:0, pz:0};

function drawBg():void {
	var bg:Sprite=new Sprite();
	bg.graphics.beginFill(0x333333);
	bg.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
	bg.graphics.endFill();
	addChild(bg);
	var tf:TextFormat=new TextFormat();
	tf.color= 0x999999;
	tf.font="_sans";
	tf.size=11;
	tf.align="right";
	var t:TextField=new TextField();
	t.width=300;
	t.defaultTextFormat=tf;
	t.text="Press SPACEBAR to change particles shape";
	t.x=stage.stageWidth-t.width-10;
	t.selectable=false;
	bg.addChild(t);
}

function addParticle(x:Number, y:Number, z:Number):void {
	var p:MovieClip=new MovieClip();
	p.graphics.beginFill(0xcccccc);
	p.graphics.drawCircle(0, 0, 5);
	p.graphics.endFill();
	p.px=x;
	p.py=y;
	p.pz=z;
	particles.push(p);
}

function cycleShape():void {
	if (shapeN<3) {
		shapeN++;
	} else {
		shapeN=0;
	}
	var i:uint;
	var p:MovieClip;
	var px:Number;
	var py:Number;
	var pz:Number;
	var arad:Number;
	if (shapeN==0) {
		var a:Number=0;
		for (i=0; i0) {
				var t2:Object=particlesXY[i+1];
	
				lines.graphics.moveTo(t.x, t.y);
				lines.graphics.lineTo(t2.x, t2.y);
			}
		}
	}
}

stage.addEventListener(KeyboardEvent.KEY_UP, onkey);
function onkey(event:KeyboardEvent):void {
	if(event.keyCode==32) {
		cycleShape();
		render();
	}
}
addEventListener(Event.ENTER_FRAME, onframe);

function onframe(event:Event):void {
	var offx:Number=stage.stageWidth/2-mouseX;
	
	camera.px-=offx/5;
	if (camera.px>150) {
		camera.px=150;
	}
	if (camera.px<-150) {
		camera.px=-150;
	}
	var offy:Number=stage.stageHeight/2-mouseY;
	if(offy>70) offy=70;
	if(offy<-70) offy=-70;
	
	camera.pz+=offy/5;
	if (camera.pz>1700) {
		camera.pz=1700;
	}
	if (camera.pz<0) {
		camera.pz=0;
	}
	render();
}

function addSprites():void {
	for each (var p:MovieClip in particles) {
		addChildAt(p, 1);
	}
}

function init():void {
	for(var i:uint=0; i<1200; i++) {
		var px:Number=0;
		var py:Number=0;
		var pz:Number=0;
		addParticle(px, py ,pz);
	}
}

// main methods call
drawBg();
addChild(lines);
init();
addSprites();
cycleShape();
render();
var fr:FrameRater=new FrameRater(0xffffff);
addChild(fr);

Have fun and leave a comment if you like.

19 Comments

19 Comments

  1. _phase_O  •  Apr 3, 2008 @4:14 pm

    Pretty cool! :)

  2. Fardeen  •  Apr 4, 2008 @8:39 am

    Excellent ! love it !

  3. Jonas  •  Apr 4, 2008 @8:18 pm

    you feel tweener is better than for example tweenLite? and if u do, why? :)

  4. Pierluigi Pesenti  •  Apr 7, 2008 @5:15 pm

    eheh I don’t feel Tweener is better, it’s simply the only tweeneing class I tested so far :P

    I have just seen some samples of the new TweenMax and seems really cool. In the next few days I will do some test with it and eventually migrate :)

  5. Paul  •  Apr 9, 2008 @4:29 pm

    Oh man, I’m glad I found your blog today – good work.

    I’ve added you to my RSS feed ;-)

  6. Dark Vyper  •  Apr 15, 2008 @1:42 pm

    Nice example. It took a while for me to understand the source – nice code too!

  7. benje  •  Jul 18, 2008 @11:52 pm

    I love what you’ve done here, beautiful effect!

  8. salihozkan  •  Feb 13, 2009 @9:17 pm

    Nice!! I love it..

  9. Fluensh  •  Mar 30, 2009 @6:53 am

    awesome! May i ask the if the 3d effect is based on the tweener or based on the flash 10?

  10. Pierluigi Pesenti  •  Mar 30, 2009 @7:07 am

    fp9. The 3d calculation is simple and is done in the render function. Tweener is used just to change particles position while cycling shape.

  11. Fluensh  •  Mar 30, 2009 @8:15 am

    hmm. got it. I thought 3d was supported since fp10, but the demo can also run in fp9, so, got a little confused. after all, thanx :-)

  12. Andy Kim  •  Apr 23, 2009 @9:22 pm

    Thanks very much for the wonderful fun. It helped me as the base for this simulation which can be viewed here http://www.andykimchi.com/randomJunk/electrons/particleLove.html

  13. Pierluigi Pesenti  •  Apr 23, 2009 @11:55 pm

    eheh, it’s a pleasure to know it helped ;-)

  14. snark  •  Jun 11, 2009 @1:55 am

    Error on Line 166!!!

    function onframe(event:Event):void {

    type not found

  15. ethan  •  Jun 14, 2009 @4:37 pm

    f-ing brilliant! genius math…

  16. NishefsCids  •  Jul 2, 2009 @4:12 pm

    Очень понравился ваш блог! Подписался на rss. Буду регулярно читать.

  17. Pierluigi Pesenti  •  Jul 2, 2009 @5:10 pm

    Hi NishefsCids,

    google translates your comment in: “I like your blog! Subscribed to the rss. I regularly read it.”.
    I am very happy of this, thanks for the appreciation, but please do post comments in english cause it’s this blog’s official language ;)

    Cheers

  18. Chou Aieb  •  Apr 21, 2012 @3:16 pm

    nice work , i really like it , i have a question , is it possible to implement it in an sound spectrum , like the one you did before (the fountain Equalizer) i guess its possible and it will very good

  19. David Szucs  •  Oct 8, 2012 @11:39 am

    This is my favorite script all time. Rather than use past projects I always come back time to time to see how brilliant it is. I realised now the best part is missing somehow… the render() function. I know it by heart but let the others wonder too!

    Peace and respect!

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>