package { import flash.display.MovieClip; import flash.events.*; /** * Original AS2 Class by Keith Peters (BIT-101) * Conversion to AS3 by Eric E. Dolecki */ public class Particle extends MovieClip { private var __vx:Number = 0; private var __vy:Number = 0; private var __k:Number = .2; private var __damp:Number = .9; private var __bounce:Number = -.5; private var __grav:Number = 0; private var __bounds:Object; private var __draggable:Boolean = false; private var __edgeBehavior:String = "bounce"; private var __drag:Boolean; private var __oldx:Number; private var __oldy:Number; private var __maxSpeed:Number; private var __wander:Number = 0; private var __turn:Boolean = false; private var __springToMouse:Boolean = false; private var __mouseK:Number = .2; private var __gravToMouse:Boolean = false; private var __gravMouseForce:Number = 5000; private var __repelMouse:Boolean = false; private var __repelMouseMinDist:Number = 100; private var __repelMouseK:Number = .2; private var __springPoints:Array; private var __gravPoints:Array; private var __repelPoints:Array; private var __springClips:Array; private var __gravClips:Array; private var __repelClips:Array; private var __efClip:MovieClip; // public function Particle() { addEventListener( Event.ADDED_TO_STAGE, onAddedToStage ); init(); } private function onAddedToStage( event:Event ):void { removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage ); //can access the stage now. //trace( "added to stage" ); } private function init():void { __bounds = new Object(); setBounds( {xMin:0, yMin:0, yMax: stage.stageHeight, xMax: stage.stageWidth} ); __maxSpeed = Number.MAX_VALUE; __springPoints = new Array(); __gravPoints = new Array(); __repelPoints = new Array(); __springClips = new Array(); __gravClips = new Array(); __repelClips = new Array(); __efClip = new MovieClip(); __efClip.addEventListener( Event.ENTER_FRAME, __efHandler ); } public function set vx(nVx:Number):void { __vx = nVx; } public function get vx():Number { return __vx; } public function set vy(nVy:Number):void { __vy = nVy; } public function get vy():Number { return __vy; } public function set damp(nDamp:Number):void { __damp = nDamp; } public function get damp():Number { return __damp; } public function set bounce(nBounce:Number):void { __bounce = nBounce; } public function get bounce():Number { return __bounce; } public function set grav(nGrav:Number):void { __grav = nGrav; } public function get grav():Number { return __grav; } public function set maxSpeed( nMaxSpeed:Number ) { __maxSpeed = nMaxSpeed; } public function get maxSpeed():Number { return __maxSpeed; } public function set wander( nWander:Number ):void { __wander = nWander; } public function get wander():Number { return __wander; } public function set edgeBehavior(sEdgeBehavior:String):void { __edgeBehavior = sEdgeBehavior; } public function get edgeBehavior():String { return __edgeBehavior; } public function setBounds(oBounds) { __bounds.top = oBounds.yMin; __bounds.bottom = oBounds.yMax; __bounds.left = oBounds.xMin; __bounds.right = oBounds.xMax; } public function set draggable( bDrag:Boolean ):void { __draggable = true; if ( bDrag ) { this.addEventListener( MouseEvent.PRESS, pressHandler ); this.addEventListener( MouseEvent.RELEASE, releaseHandler ); stage.addEventListener( MouseEvent.MOUSE_UP, outsideHandler) ; // releaseOutside handler hack } else { this.removeEventListener( MouseEvent.PRESS, pressHandler ); this.removeEventListener( MouseEvent.RELEASE, releaseHandler ); stage.removeEventListener( MouseEvent.MOUSE_UP, outsideHandler ); __drag = false; } } private function pressHander( e:MouseEvent ):void { this.startDrag(); __drag = true; } private function releaseHandler( e:MouseEvent ):void { this.stopDrag(); __drag = false; } private function outsideHandler( e:MouseEvent ):void { this.stopDrag(); __drag = false; } public function get draggable():Boolean { return __draggable; } public function set turnToPath(bTurn:Boolean):void { __turn = bTurn; } public function get turnToPath():Boolean { return __turn; } private function __efHandler( e:Event ):void { __move(); } private function __move():void { var dx; var dy; var distSQ; var dist; var force; var tx; var ty; var point; var clip; var k; var minDist; if ( __drag ) { __vx = this.x - __oldx; __vy = this.y - __oldy; __oldx = this.x; __oldy = this.y; } else { if ( __springToMouse ) { __vx += ( stageX - this.x ) * __mouseK; __vy += ( stageY - this.y ) * __mouseK; } if ( __gravToMouse ) { dx = stageX - this.x; dy = stageY - this.y; distSQ = dx * dx + dy * dy; dist = Math.sqrt( distSQ ); force = __gravMouseForce / distSQ; __vx += force * dx / dist; __vy += force * dy / dist; } if ( __repelMouse ) { dx = stageX - this.x; dy = stageY - this.y; dist = Math.sqrt(dx * dx + dy * dy); if (dist < __repelMouseMinDist) { tx = stageX - __repelMouseMinDist * dx / dist; ty = stageY - __repelMouseMinDist * dy / dist; __vx += (tx - this.x) * __repelMouseK; __vy += (ty - this.y) * __repelMouseK; } } for ( var sp:uint=0; sp < __springPoints.length; sp++ ) { point = __springPoints[sp]; __vx += (point.x - this.x) * point.k; __vy += (point.y - this.y) * point.k; } for ( var gp:uint = 0; gp < __gravPoints.length; gp++ ) { point = __gravPoints[gp]; dx = point.x - this.x; dy = point.y - this.y; distSQ = dx * dx + dy * dy; dist = Math.sqrt( distSQ ); force = point.force / distSQ; __vx += force * dx / dist; __vy += force * dy / dist; } for ( var rp:uint = 0; rp < __repelPoints.length; rp++ ) { point = __repelPoints[rp]; dx = point.x - this.x; dy = point.y - this.y; dist = Math.sqrt( dx * dx + dy * dy ); if (dist < point.minDist) { tx = point.x - point.minDist * dx / dist; ty = point.y - point.minDist * dy / dist; __vx += (tx - this.x) * point.k; __vy += (ty - this.y) * point.k; } } for ( var sc:uint = 0; sc < __springClips.length; sc++ ) { clip = __springClips[sc].clip; k = __springClips[sc].k; __vx += (clip.x - this.x) * k; __vy += (clip.y - this.y) * k; } for ( var gc:uint = 0; gc < __gravClips.length; gc++ ) { clip = __gravClips[gc].clip; dx = clip.x - this.x; dy = clip.y - this.y; distSQ = dx * dx + dy * dy; dist = Math.sqrt( distSQ ); force = __gravClips[gc].force / distSQ; __vx += force * dx / dist; __vy += force * dy / dist; } for ( var rc:uint= 0; rc < __repelClips.length; rc++ ) { clip = __repelClips[rc].clip; minDist = __repelClips[rc].minDist; k = __repelClips[rc].k; dx = clip.x - this.x; dy = clip.y - this.y; dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { tx = clip.x - minDist * dx / dist; ty = clip.y - minDist * dy / dist; __vx += (tx - this.x) * k; __vy += (ty - this.y) * k; } } __vx += Math.random() * __wander - __wander / 2; __vy += Math.random() * __wander - __wander / 2; __vy += __grav; __vx *= damp; __vy *= damp; var speed = Math.sqrt(__vx * __vx + __vy * __vy); if (speed > __maxSpeed) { __vx = __maxSpeed * __vx / speed; __vy = __maxSpeed * __vy / speed; } if (__turn) { this.rotation = Math.atan2(__vy, __vx) * 180 / Math.PI; } this.x += __vx; this.y += __vy; if(__edgeBehavior == "wrap") { if ( this.x > __bounds.right + this.width/2 ) { this.x = __bounds.left - this.width/2; } else if ( this.x < __bounds.left - this.width/2) { this.x = __bounds.right + this.width/2; } if( this.y > __bounds.bottom + this.height/2) { this.y = __bounds.top - this.height/2; } else if (this.y < __bounds.top - this.height/2) { this.y = __bounds.bottom + this.height/2; } } else if(__edgeBehavior == "bounce") { if ( this.x > __bounds.right - this.width/2) { this.x = __bounds.right - this.width/2; __vx *= __bounce; } else if (this.x < __bounds.left + this.width/2){ this.x = __bounds.left + this.width/2; __vx *= __bounce } if( this.y > __bounds.bottom - this.height/2){ this.y = __bounds.bottom - this.height/2; __vy *= __bounce } else if ( this.y < __bounds.top + this.height/2){ this.y = __bounds.top + this.height/2; __vy *= __bounce; } } else if(__edgeBehavior == "remove") { if( this.x > __bounds.right + this.width/2 || this.x < __bounds.left - this.width/2 || this.y > __bounds.bottom + this.height/2 || this.y < __bounds.top - this.height/2){ removeChild( this ); } } if( stage != null ) stage.invalidate(); } }; public function gravToMouse( bGrav:Boolean, force:Number ):void { if (bGrav) { if (!force) { var force = 1000; } __gravMouseForce = force; __gravToMouse = true; } else { __gravToMouse = false; } } public function springToMouse( bSpring:Boolean, force:Number ):void { if (bSpring) { if (!force) { var force = .1; } __mouseK = force; __springToMouse = true; } else { __springToMouse = false; } } public function repelMouse( bRepel:Boolean, force:Number, minDist:Number ):void { if (bRepel) { if (!force) { var force = .1; } if (!minDist) { var minDist = 100; } __repelMouseK = force; __repelMouseMinDist = minDist; __repelMouse = true; } else { __repelMouse = false; } } public function addSpringPoint(x:Number, y:Number, force:Number):Number { if (!force) { var force = .1; } __springPoints.push( {x:x, y:y, k:force} ); return __springPoints.length - 1; } public function addGravPoint(x:Number, y:Number, force:Number):Number { if (!force) { var force = 1000; } __gravPoints.push( {x:x, y:y, force:force} ); return __gravPoints.length - 1; } public function addRepelPoint( x:Number, y:Number, force:Number, minDist:Number ):Number { if (!force) { var force = .1; } if (!minDist) { var minDist = 100; } __repelPoints.push({x:x, y:y, k:force, minDist:minDist}); return __repelPoints.length - 1; } public function addSpringClip(clip:MovieClip, force:Number):Number { if (!force) { var force = .1; } __springClips.push( {clip:clip, k:force} ); return __springClips.length - 1; } public function addGravClip(clip:MovieClip, force:Number):Number { if (!force) { var force = 1000; } __gravClips.push({clip:clip, force:force}); return __gravClips.length - 1; } public function addRepelClip( clip:MovieClip, force:Number, minDist:Number ):Number { if ( !force ) { var force = .1; } if ( !minDist ) { var minDist = 100; } __repelClips.push( {clip:clip, k:force, minDist:minDist} ); return __repelClips.length - 1; } public function removeSpringPoint( index:Number ):void { __springPoints.splice(index, 1); } public function removeGravPoint( index:Number ):void { __gravPoints.splice(index, 1); } public function removeRepelPoint( index:Number ):void { __repelPoints.splice(index, 1); } public function removeSpringClip(index:Number):void { __springClips.splice(index, 1); } public function removeGravClip(index:Number):void { __gravClips.splice(index, 1); } public function removeRepelClip(index:Number):void { __repelClips.splice(index, 1); } public function clearSpringPoints():void { __springPoints = new Array(); } public function clearGravPoints():void { __gravPoints = new Array(); } public function clearRepelPoints():void { __repelPoints = new Array(); } public function clearSpringClips():void { __springClips = new Array(); } public function clearGravClips():void { __gravClips = new Array(); } public function clearRepelClips():void { __repelClips = new Array(); } } }