All pastes #2101973 Raw Edit

Miscellany

public text v1 · immutable
#2101973 ·published 2012-01-10 19:17 UTC
rendered paste body

/********************************************\
/******                                ******\
/****									 ****\
/**		DeviantGear Particle System		   **\
/****								   	 ****\
/******                                ******\
\********************************************/



/********************************************/
/*											*/
/*				 Includes etc				*/
/*											*/
/********************************************/

import flash.utils.Timer
import flash.geom.Point
import flash.display.DisplayObject
import flash.events.Event;

var sys = new Object()
sys.useSettings 	= new Array()
sys.particle 		= new Array()
sys.spawnDir 		= new Array()
sys.brtColor 		= new Array()
sys.dthColor 		= new Array()



/********************************************/
/*											*/
/*				 Settings					*/
/*											*/
/********************************************/

	// all distances in pixels
	// all angles in degrees
	// all time in seconds

/*** GENERAL ***/

		// the class(es) to use for particles
	sys.particle[0]			= "dot"

		// for accurate time and speed calculations, this should match the sys.fps setting of flash!
	sys.fps				= 30

		// time to pass after starting the simulation before this system starts creating particles ( seconds, offset )
	sys.strtTime		= new Array( 0, 0 )
	
		// time to pass after starting the simulation before this system stops creating particles ( seconds, offset ) 0 = don't stop 
	sys.stpTime			= new Array( 0, 0 )
	
		// interval between bursts of creating particles	( seconds, offset )
	sys.burstIntrvl		= new Array( 0, 0 )
	
		// amount of particles per burst					( seconds, offset )
	sys.burstSize		= new Array( 0, 0 )
	
		// true : the origin of the system follows the cursor. speed based on accel values
	sys.bFollowMouse	= true
	
	
/*** LIFE AND DEATH ***/
	
		// amount of particles to spawn per second			( amount, offset )
	sys.pps				= new Array( 1, 0 )
	
		// true : interpret pps as seconds per particle, i.e. seconds between spawns
	sys.bSpp			= false
	
		// lifetime of indivudal particles in seconds		( seconds, offset ) 0 seconds = unlimited
	sys.lifetime		= new Array( 0, 0 )
	
		// maximum amount of particles to be alive			0 = unlimited
	sys.max				= 0
	
		// behaviour when trying to spawn a new particle while max is reached:
		// true  : kill oldest existing particle
		// false : don't spawn new particle
	sys.bAutokill		= false


/*** SPAWN LOCATION ***/
	sys.useSettings['spawnloc'] = false
	
		// spawn radius from origin							( radius, offset )
	sys.spawnRad		= new Array( 0, 0 )
	
		// spawn direction(s) from origin					( angle, offset ) all directions: 0, 360
	sys.spawnDir[0]		= new Array( 0, 360 )
		
		// true : spawn new particles in front of existing particles
	sys.bSpawnInFront	= false



/*** VELOCITY AND ACCELERATION ***/
	sys.useSettings['velocity'] = false
	
		// velocity at birth							( angle, offset, velocity, offset ) all directions: 0, 360
	sys.brtVeloc			= new Array( 0, 360, 0, 0 )
	
		// velocity at death								( angle, offset, velocity, offset ) no change from brtVeloc: -1
	sys.dthVeloc			= new Array( -1, -1, -1, -1 )
	
		// for using spawnRad: use velocity of brtVeloc to move away from origin
	sys.bAwayFromOrigin		= false
	
		// behaviour for determining velocity throughout lifetime:
		// true  : acceleration changes velocity
		// false : aim to end lifetime using dthVeloc (acceleration has no effect)
	sys.bUseAccel = true
	
		// acceleration by particle	at birth			( angle, offset, velocity, offset )
	sys.brtAccel		= new Array( 0, 0, 0, 0 )
	
		// acceleration by particle	at death			( angle, offset, velocity, offset ) no change from brtAccel: -1
	sys.dthAccel		= new Array( -1, -1, -1, -1 )
	
		// interpretation of acceleration values:
		// false : accel defines direction to accelerate into
		// true  : brtAccel defines point from origin to accelerate towards, dthAccel determines velocity
	sys.bConverge		= true


/*** ENVIRONMENT ***/
	sys.useSettings['environment'] = false
	

		// magnitude of gravity affecting particles
	sys.grav			= 0
	
		// wind affecting particles						// ( angle, magnitude )
	sys.wind			= new Array( 0, 0 )
	
		// amount of wind fluctuation
	sys.windfluct		= 0
	
		// friction affecting particles. 1 is no friction, lower than 1 is acceleration
	sys.fric	 		= 1


/*** OPACITY ***/
	sys.useSettings['opacity'] = false
	
		// fade throughout lifetime						// ( amount, offset )
	sys.fade			= new Array( 0, 0 )
	
		// opacity at birth								// ( alpha, offset )
	sys.brtAlpha		= new Array( 1, 0 )
	
		// opacity at death (fade is ignored if set)	// ( alpha, offset )
	sys.dthAlpha		= new Array( 1, 0 )
	
		 // true : oscillate between brt and dth values with fade speed. oscillates once in lifetime if fade is 0
	sys.bAlphaOscillate = false
	
	
/*** COLOR ***/
	sys.useSettings['color'] = false
	
		// the color(s) of the particle at birth		( r, g, b, offset) offset range is 0 to 1
	sys.brtColor[0]		= new Array( 0, 0, 0, 0 )
	
		// the color(s) of the particle at death		( r, g, b, offset) offset range is 0 to 1
	sys.dthColor[0]		= new Array( 0, 0, 0, 0 )
	
		// when defining multiple possible birth and death colors, link their numbers
	sys.bLinkColors		= false
	
		// speed at which color changes from brt towards and past dth if lifetime is unlimited ( speed, offset )
	sys.spdColor		= new Array( 0, 0 )
	
			 // true : oscillate between brt and dth values at speed defined by spd. oscillates once in lifetime if spd is 0
	sys.bColorOscillate	= false
	
	
/*** SIZE ***/
	sys.useSettings['size'] = false
	
		// growth throughout lifetime					// ( width, offset, height, offset )
	sys.growth			= new Array( 0, 0, 0, 0 )
	
		// size at birth								// ( width, offset, height, offset )
	sys.brtSize			= new Array( 1, 0, 1, 0 )
	
		// size at death 								// ( width, offset, height, offset )
	sys.dthSize			= new Array( 1, 0, 1, 0 )
	
		// link width and height sizes
	sys.bLinkSize		= true
	
		 // true : oscillate between brt and dth values with growth speed. oscillates once in lifetime if growth is 0
	sys.bSizeOscillate	= false


/*** ROTATION ***/
	sys.useSettings['rotation'] = false
	
		// rotation speed throughout lifetime			( speed, offset )
	sys.rotate			= new Array( 0, 0 )
		
		// rotation at birth							( angle, offset )
	sys.brtRot			= new Array( 0, 0 )
	
		// rotation at death (rotate is ignored if set)	( angle, offset ) -1 = no change from brtRot
	sys.dthRot			= new Array( 0, 0 )
	
		// friction affecting particles. 1 is no friction, lower than 1 is acceleration. no effect if dthRot is set
	sys.rotFric	 		= 1
	
		// true : align particles to movement direction (including gravity etc)
	sys.bRotToVeloc		= true
	
		// the particle's 'up' direction (useful for bRotToVeloc)
	sys.rotUp			= 0
	
		// true : calculate rotations relative to parent
	sys.bRotParent		= true



/********************************************/
/*											*/
/*				End of Settings				*/
/*											*/
/********************************************/



/********************************************/
/*											*/
/*					Library					*/
/*											*/
/********************************************/

function rand( min = 1, max = 0 ) {
	if ( max == 0 ) {
		max = min
		min = 0
	}
	return Math.random() * ( max - min ) + min
}

function iRand( min = 1, max = 0 ) {
	if ( max == 0 ) {
		max = min
		min = 0
	}
	var ret = round( rand( min-0.5, max+0.5 ) )
	if ( ret == max+1 ) ret = max
	return ret
}

function bRand() {
	if ( iRand() == 1 ) return true
	else return false
}

function sRand() {
	if ( bRand() ) return 1
	else return -1
}

function offset( base, offset ) {
	return base + ( rand(offset) * sRand() )
}

function offsetRGB( r, g, b, offset ) {
	var pr = rand()
	var pg = rand()
	var pb = rand()
	var pt = pr + pg + pb
	
	var nr = limit( r + pr/pt * sRand() * offset * 255, 0, 255 )
	var ng = limit( g + pg/pt * sRand() * offset * 255, 0, 255 )
	var nb = limit( b + pb/pt * sRand() * offset * 255, 0, 255 )
	
	return { 0: nr, 1: ng, 2: nb }
}

function round( val, dec = 0 ) {
	return Math.round( val * Math.pow( 10, dec ) ) / Math.pow( 10, dec )
}

function sign( val ) {
	if ( val == 0 ) return 0
	else return val / Math.abs(val)
}

function deg2vec( deg, dist ) {
	var rad = deg * (Math.PI / 180)
	return { x: round( Math.sin(rad) * dist, 10), y: round( Math.cos(rad) * dist, 10) }
}

function vec2deg( vx, vy ) {
	return ( Math.atan2( 0, -1 ) - Math.atan2( vx, vy ) ) * 180/pi()
}

function input2vec( input ) {
	return deg2vec( offset( input[0], input[1] ), offset( input[2]/sys.fps, input[3]/sys.fps ) )
}

function transfer( strt, crrnt, end, min, max ) {
	return ( crrnt - strt ) / ( end - strt ) * ( max - min ) + min
}

function cartReplace( haystack, cart, needle, stamp = null ) {
	if ( stamp == null ) { stamp = haystack }
	for ( var n=0; n<stamp.length; n++ ) {
		if ( haystack[n] == needle ) {
			haystack[n] = cart[n]
		}
	}
	return haystack
}

function magnitude( vx, vy )
{
	return Math.sqrt( vx * vx + vy * vy)
}

function normalize( vx, vy )
{
	var mag = magnitude( vx, vy )
	if (mag == 0) mag = 1
	return { x: vx/mag, y: vy/mag }
}

function decimals( val ) {
	return ( val - round(val))
}

function limit( val, min, max ){
	if (val < min) { val = min }
	if (val > max) { val = max }
	return val
}

function pi() { return Math.PI }

function bsign( val ) {
	if ( val >= 0 ) { return true }
	else if ( val < 0 ) { return false }
}

function rgb( r, g, b ) {
	return ( ( r << 16 ) | ( g << 8 ) | b )
}

function setColor( subject, col ) {
	var myColor:ColorTransform = subject.transform.colorTransform;
	myColor.color = rgb( col[0], col[1], col[2] );
	subject.transform.colorTransform = myColor;
}



/********************************************/
/*											*/
/*				Main Functions				*/
/*											*/
/********************************************/

/*** GENERAL ***/

var particles = new Array()
var origin :Object = { x: 0, y: 0 }


/*** WIND ***/

sys.wind.vec = deg2vec( sys.wind[0], sys.wind[1] )
sys.wind.mag = 1
sys.wind.aim = 0

/*** BURSTS ***/

var inBurst = new Array()
var doSpawn = false
var doBurst = false
var useBursts = false

if ( ( sys.burstIntrvl[0] != 0 || sys.burstIntrvl[1] !=0 ) && ( sys.burstSize[0] != 0 || sys.burstSize[1] !=0 ) ) useBursts = true
var nextBurstIntrvl = offset( sys.burstIntrvl[0], sys.burstIntrvl[1] )
var rlBurstSize = offset( sys.burstSize[0], sys.burstSize[1] )

function startBurst( e:Event) {
	doBurst = true
	createParticle()
	
	nextBurstIntrvl = offset( sys.burstIntrvl[0], sys.burstIntrvl[1] )
	rlBurstSize = offset( sys.burstSize[0], sys.burstSize[1] )
	
	var tStartBurst:Timer = new Timer( nextBurstIntrvl * 1000, 1 )
	tStartBurst.addEventListener( TimerEvent.TIMER, startBurst )
	tStartBurst.start()
}

/*** SYSTEM ***/

var tStartSystem:Timer = new Timer( offset( sys.strtTime[0], sys.strtTime[1] ) * 1000, 1 )
tStartSystem.addEventListener( TimerEvent.TIMER, startSystem )
tStartSystem.start()

if ( sys.stpTime[0] != 0 || sys.stpTime[1] != 0 ) {
	var tStopSystem:Timer = new Timer( offset( sys.stpTime[0], sys.stpTime[1] ) * 1000, 1 )
	tStopSystem.addEventListener( TimerEvent.TIMER, stopSystem )
	tStopSystem.start()
}

function startSystem( e:Event ) {
	doSpawn = true
	doBurst = true
	createParticle()
	
	if ( useBursts ) {
		var tStartBurst:Timer = new Timer( nextBurstIntrvl * 1000, 1 )
		tStartBurst.addEventListener( TimerEvent.TIMER, startBurst )
		tStartBurst.start()
	}
}

function stopSystem( e:Event ) {
	doSpawn = false
}

this.addEventListener( Event.ENTER_FRAME, updateSystem )

function updateSystem( e:Event ) {
	if ( sys.bFollowMouse )	origin = { x: this.mouseX, y: this.mouseY }
}


/********************************************/
/*											*/
/*			Particle Functions				*/
/*											*/
/********************************************/

function getNextSpawnTime() {
	var ret
	var realpps = new Array( sys.pps[0], sys.pps[1 ])
	
	if ( sys.bSpp ) {
			realpps[0] = 1 / sys.pps[0]
		if ( sys.pps[1] != 0 )
			realpps[1] = 1 / sys.pps[1]
	}
	
	if (sys.pps[1] == 0)	ret = 1000/realpps[0]
	else				ret = 1000/offset( realpps[0], realpps[1] )
	
	if ( ret < 0 )		ret = 0
	
	return ret
}

function createParticle( e:Event = null ) {
	
	/*** INITIALS ***/
	
	if ( !doSpawn || ( useBursts && !doBurst ) ) return
	
	var tCreateParticle:Timer = new Timer( getNextSpawnTime(), 1 )
	tCreateParticle.addEventListener( TimerEvent.TIMER, createParticle )
	tCreateParticle.start()
	
	var randPrtcle = iRand( sys.particle.length-1 )
	var ClassReference:Class = getDefinitionByName(sys.particle[randPrtcle]) as Class
    var prtcl = new ClassReference()
	
	prtcl.forceSmoothing = true
	
	/*** LIFE AND DEATH ***/
	
	if ( sys.lifetime[0] != 0 || sys.lifetime[1] != 0 )
	{
		prtcl.lifetime 	= offset( sys.lifetime[0], sys.lifetime[1] )
		if ( prtcl.lifetime < 0 ) prtcl.lifetime = 0
		prtcl.birthtime	= new Date().getTime()
		prtcl.deathtime = prtcl.birthtime + prtcl.lifetime * 1000
		prtcl.halflife = transfer( 0, 0.5, 1, prtcl.birthtime, prtcl.deathtime )
	}
	
	if ( particles.length == sys.max && sys.max != 0 )	{
		if ( sys.bAutokill ) {
			removeChild( particles.shift() )
		} else {
			return
		}
	}
	
	
	/*** SPAWN LOCATION ***/
	
	var spawnLoc = new Object()
	var spawnOffset = new Object()
	
	if ( sys.useSettings['spawnloc'] ) {
		var chosenDir	= iRand( sys.spawnDir.length-1 )
		var realDir		= offset(	sys.spawnDir[chosenDir][0],	sys.spawnDir[chosenDir][1]	)
		var realRad		= offset(		sys.spawnRad[0],			sys.spawnRad[1]				)
		spawnOffset = deg2vec(		realDir,				realRad					)
		
		spawnLoc.x = origin.x + spawnOffset.x
		spawnLoc.y = origin.y + spawnOffset.y
	} else {
		spawnLoc.x = origin.x
		spawnLoc.y = origin.y
	}
	
	prtcl.x = spawnLoc.x
	prtcl.y = spawnLoc.y
	
	
	/*** VELOCITY AND ACCELERATION ***/
	
	prtcl.veloc = new Object()
	prtcl.brtVeloc = new Object()
	prtcl.brtAccel = new Object()
	
	if ( sys.useSettings['velocity'] ) {
			
		prtcl.brtVeloc = input2vec( sys.brtVeloc )
		var realDthVeloc = new Array( sys.dthVeloc[0], sys.dthVeloc[1], sys.dthVeloc[2], sys.dthVeloc[3] )
		prtcl.dthVeloc = input2vec( cartReplace( realDthVeloc, sys.brtVeloc, -1 ) )
		cartReplace( prtcl.dthVeloc, sys.brtVeloc, -1, realDthVeloc )
		
		if ( sys.bAwayFromOrigin && ( sys.spawnRad[0] != 0 || sys.spawnRad[1] != 0 ) ) {
			prtcl.brtVeloc.x = normalize( spawnOffset.x, spawnOffset.y ).x * magnitude( prtcl.brtVeloc.x, prtcl.brtVeloc.y )
			prtcl.brtVeloc.y = normalize( spawnOffset.x, spawnOffset.y ).y * magnitude( prtcl.brtVeloc.x, prtcl.brtVeloc.y )
		} 
		
		prtcl.brtAccel = input2vec( sys.brtAccel )
		var realDthAccel = new Array( sys.dthAccel[0], sys.dthAccel[1], sys.dthAccel[2], sys.dthAccel[3] )
		prtcl.dthAccel = input2vec( cartReplace( realDthAccel, sys.brtAccel, -1 ) )
		cartReplace( prtcl.dthAccel, prtcl.brtAccel, -1, realDthAccel )

	} else {
		prtcl.brtVeloc.x = 0
		prtcl.brtVeloc.y = 0
		
		prtcl.brtAccel.x = 0
		prtcl.brtAccel.y = 0
	}
	
	prtcl.veloc.x = prtcl.brtVeloc.x
	prtcl.veloc.y = prtcl.brtVeloc.y
	
	
	/*** OPACITY ***/
	
	if ( sys.useSettings['opacity'] ) {
		prtcl.brtAlpha = offset( sys.brtAlpha[0], sys.brtAlpha[1] )
		prtcl.dthAlpha = offset( sys.dthAlpha[0], sys.dthAlpha[1] )
		prtcl.fade = offset( sys.fade[0], sys.fade[1] )
		
		prtcl.alpha = prtcl.brtAlpha
	}
		
	
	/*** COLOR ***/
	
	if ( sys.useSettings['color'] ) {
		var rndBrtColor = iRand( sys.brtColor.length-1 )
		var rndDthColor
		if ( sys.bLinkColors && ( sys.spdColor[0] != 0 || sys.spdColor[1] != 0 ) && sys.dthColor[rndBrtColor] != null ) rndDthColor = rndBrtColor
		else rndDthColor = iRand( sys.dthColor.length-1 )
		
		prtcl.brtColor = offsetRGB( sys.brtColor[rndBrtColor][0], sys.brtColor[rndBrtColor][1], sys.brtColor[rndBrtColor][2], sys.brtColor[rndBrtColor][3] )
		if ( sys.spdColor[0] == 0 && sys.spdColor[1] == 0 ) {
			prtcl.dthColor = prtcl.brtColor
		} else {
			prtcl.dthColor = offsetRGB( sys.dthColor[rndDthColor][0], sys.dthColor[rndDthColor][1], sys.dthColor[rndDthColor][2], sys.dthColor[rndDthColor][3] )
			
		}
		
		prtcl.spdColor = offset( sys.spdColor[0], sys.spdColor[1] )
		prtcl.spdClr = new Array()
		prtcl.spdClr[0] = prtcl.spdColor * sign( sys.dthColor[rndDthColor][0] - sys.brtColor[rndBrtColor][0] )
		prtcl.spdClr[1] = prtcl.spdColor * sign( sys.dthColor[rndDthColor][1] - sys.brtColor[rndBrtColor][2] )
		prtcl.spdClr[2] = prtcl.spdColor * sign( sys.dthColor[rndDthColor][1] - sys.brtColor[rndBrtColor][2] )
		
		prtcl.crrntColor = new Array()
		prtcl.crrntColor[0] = prtcl.brtColor[0]
		prtcl.crrntColor[1] = prtcl.brtColor[1]
		prtcl.crrntColor[2] = prtcl.brtColor[2]
		
		setColor( prtcl, prtcl.crrntColor )
	}
	
	
	/*** SIZE ***/
	
	if ( sys.useSettings['size'] ) {
		prtcl.brtSizeX = offset( sys.brtSize[0], sys.brtSize[1] )
		prtcl.dthSizeX = offset( sys.dthSize[0], sys.dthSize[1] )
		prtcl.growthX = offset( sys.growth[0], sys.growth[1] )
		
		prtcl.scaleX = prtcl.brtSizeX
		
		if ( sys.bLinkSize ) {
			prtcl.brtSizeY = prtcl.brtSizeX
			prtcl.dthSizeY = prtcl.dthSizeX
			prtcl.growthY = prtcl.growthX
			
			prtcl.scaleY = prtcl.scaleX
		} else {
			prtcl.brtSizeY = offset( sys.brtSize[2], sys.brtSize[3] )
			prtcl.dthSizeY = offset( sys.dthSize[2], sys.dthSize[3] )
			prtcl.growthY = offset( sys.growth[2], sys.growth[3] )
			
			prtcl.scaleY = prtcl.brtSizeY
		}
	}
	
	
	/*** ROTATION ***/
	
	if ( sys.useSettings['assd'] ) {
		if ( sys.bRotToVeloc ) {
			prtcl.brtRot = vec2deg( prtcl.brtVeloc.x, prtcl.brtVeloc.y )
		} else {
			prtcl.brtRot = offset( sys.brtRot[0], sys.brtRot[1] )
			if ( sys.bRotParent ) {
				prtcl.brtRot += this.rotation
			}
		}
		
		prtcl.rot = offset( sys.rotate[0], sys.rotate[1] )
		prtcl.dthRot = offset( sys.dthRot[0], sys.dthRot[1] )
		
		if ( sys.bRotParent ) {
			prtcl.dthRot += this.rotation
		}
		
		prtcl.rotation = prtcl.brtRot - sys.rotUp
	}

	
	/*** CREATION ***/
	
	prtcl.addEventListener( Event.ENTER_FRAME, updateParticle )
	prtcl.cacheAsBitmap = true 
	
	particles.push( prtcl )
	inBurst.push( prtcl )
	
	if ( inBurst.length >= rlBurstSize && useBursts) {
		inBurst = new Array()
		doBurst = false
	}
	
	if ( sys.bSpawnInFront ) addChild( prtcl )
	else addChildAt( prtcl, 0 )
}

function updateParticle( e:Event ) {
	
	var prtcl = e.currentTarget as DisplayObject
	var now = new Date().getTime()
	
	
	/*** LIFE AND DEATH ***/
	
	if ( sys.lifetime[0] != 0 || sys.lifetime[1] != 0 ) {
		if 	( now > prtcl.deathtime ) {
			killParticle( prtcl )
		}
	}
	
	
	/*** VELOCITY AND ACCELERATION ***/
	
	if ( sys.useSettings['velocity'] ) {
		if ( sys.bUseAccel && ( sys.brtAccel[2] != 0 || sys.brtAccel[3] || ( sys.dthAccel[2] != 0 && sys.dthAccel[2] != -1 ) || ( sys.dthAccel[3] != 0 && sys.dthAccel[3] != -1 ) ) ) {
			if ( sys.bConverge ) {
				var normal = normalize( origin.x + prtcl.brtAccel.x - prtcl.x, origin.y + prtcl.brtAccel.y - prtcl.y )
				var mag = magnitude( prtcl.dthAccel.x, prtcl.dthAccel.y)
				prtcl.veloc.x += normal.x * mag
				prtcl.veloc.y += normal.y * mag
			} else {
				if (prtcl.lifetime == null) {
					prtcl.veloc.x += prtcl.brtAccel.x
					prtcl.veloc.y += prtcl.brtAccel.y
				} else {
					prtcl.veloc.x += transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtAccel.x, prtcl.dthAccel.x )
					prtcl.veloc.y += transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtAccel.y, prtcl.dthAccel.y )
				}
			}
		} else if ( sys.dthVeloc[0] != -1 || sys.dthVeloc[2] != -1 ) {
			if (prtcl.lifetime == null) {
				prtcl.veloc.x = prtcl.brtVeloc.x
				prtcl.veloc.y = prtcl.brtVeloc.y
			} else {
				prtcl.veloc.x = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtVeloc.x, prtcl.dthVeloc.x )
				prtcl.veloc.y = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtVeloc.y, prtcl.dthVeloc.y )
			}
		}
	}

	
	
	/*** ENVIRONMENT ***/
	
	if ( sys.useSettings['environment'] ) {
		
		if ( sys.fric != 0 ) {
			prtcl.veloc.x /= sys.fric
			prtcl.veloc.y /= sys.fric
		}
		
		if ( now > sys.wind.aim ) {
			sys.wind.startMag = sys.wind.mag
			sys.wind.strt = now
			sys.wind.aim = now + rand( 0.2, 5 ) / sys.windfluct * 1000 
			sys.wind.aimMag = rand( -0.2, 1.8 )
		}
		
		sys.wind.mag = transfer( sys.wind.strt, now, sys.wind.aim, sys.wind.startMag, sys.wind.aimMag )
		prtcl.veloc.x += sys.wind.vec.x * sys.wind.mag
		prtcl.veloc.y += sys.wind.vec.y * sys.wind.mag

		
		prtcl.veloc.y += sys.grav/sys.fps
	}
	
	
	/*** LOCATION UPDATE ***/
	
	prtcl.x += prtcl.veloc.x
	prtcl.y += prtcl.veloc.y
	
	
	/*** OPACITY ***/
	
	if ( sys.useSettings['opacity'] ) {
		
		if ( prtcl.fade != 0 ) {
			prtcl.alpha += prtcl.fade
			
			if ( sys.bAlphaOscillate) {
				if ( bsign(prtcl.fade) && prtcl.alpha > prtcl.dthAlpha ||
				!bsign(prtcl.fade) && prtcl.alpha < prtcl.dthAlpha ) {
					prtcl.dthAlpha = prtcl.brtAlpha
					prtcl.brtAlpha = prtcl.alpha
					prtcl.fade = -prtcl.fade
				}
			}
		} else if (prtcl.lifetime != null) {
			if (sys.bAlphaOscillate) {
				if ( now < prtcl.halflife ) {
					prtcl.alpha = transfer( prtcl.birthtime, now, prtcl.halflife , prtcl.brtAlpha, prtcl.dthAlpha )
				} else {
					prtcl.alpha = transfer( prtcl.halflife, now, prtcl.deathtime, prtcl.dthAlpha, prtcl.brtAlpha )
				}
			} else {
				prtcl.alpha = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtAlpha, prtcl.dthAlpha )
			}
		}
	}
	
	
	/*** COLOR ***/
	
	if ( sys.useSettings['color'] ) {
		if ( prtcl.lifetime != null ) {
			if (sys.bColorOscillate) {
				if ( now < prtcl.halflife ) {
					prtcl.crrntColor[0] = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.brtColor[0], prtcl.dthColor[0] )
					prtcl.crrntColor[1] = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.brtColor[1], prtcl.dthColor[1] )
					prtcl.crrntColor[2] = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.brtColor[2], prtcl.dthColor[2] )
				} else {
					prtcl.crrntColor[0] = transfer( prtcl.halflife, now, prtcl.deathtime, prtcl.dthColor[0], prtcl.brtColor[0] )
					prtcl.crrntColor[1] = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.dthColor[1], prtcl.brtColor[1] )
					prtcl.crrntColor[2] = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.dthColor[2], prtcl.brtColor[2] )
				}
			} else {
				prtcl.crrntColor[0] = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtColor[0], prtcl.dthColor[0] )
				prtcl.crrntColor[1] = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtColor[1], prtcl.dthColor[1] )
				prtcl.crrntColor[2] = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtColor[2], prtcl.dthColor[2] )
			}
		} else {
			if (sys.bColorOscillate) {
				if ( bsign(prtcl.spdClr[0]) && prtcl.crrntColor[0] >= prtcl.dthColor[0] ||
				!bsign(prtcl.spdClr[0]) && prtcl.crrntColor[0] <= prtcl.dthColor[0] ) {
					prtcl.dthColor[0] = prtcl.brtColor[0]
					prtcl.brtColor[0] = prtcl.crrntColor[0]
					prtcl.spdClr[0] = -prtcl.spdClr[0]
				}
				if ( bsign(prtcl.spdClr[1]) && prtcl.crrntColor[1] >= prtcl.dthColor[1] ||
				!bsign(prtcl.spdClr[1]) && prtcl.crrntColor[1] <= prtcl.dthColor[1] ) {
					prtcl.dthColor[1] = prtcl.brtColor[1]
					prtcl.brtColor[1] = prtcl.crrntColor[1]
					prtcl.spdClr[1] = -prtcl.spdClr[1]
				}
				if ( bsign(prtcl.spdClr[2]) && prtcl.crrntColor[2] >= prtcl.dthColor[2] ||
				!bsign(prtcl.spdClr[2]) && prtcl.crrntColor[2] <= prtcl.dthColor[2] ) {
					prtcl.dthColor[2] = prtcl.brtColor[2]
					prtcl.brtColor[2] = prtcl.crrntColor[2]
					prtcl.spdClr[2] = -prtcl.spdClr[2]
				}
			}
			prtcl.crrntColor[0] += sign( prtcl.dthColor[0] - prtcl.brtColor[0] ) * Math.abs(prtcl.spdClr[0])
			prtcl.crrntColor[1] += sign( prtcl.dthColor[1] - prtcl.brtColor[1] ) * Math.abs(prtcl.spdClr[1])
			prtcl.crrntColor[2] += sign( prtcl.dthColor[2] - prtcl.brtColor[2] ) * Math.abs(prtcl.spdClr[2])
		}
		
		prtcl.crrntColor[0] = limit( prtcl.crrntColor[0], 0, 255 )
		prtcl.crrntColor[1] = limit( prtcl.crrntColor[1], 0, 255 )
		prtcl.crrntColor[2] = limit( prtcl.crrntColor[2], 0, 255 )
		
		setColor( prtcl, prtcl.crrntColor )
	}
	
	
	/*** SIZE ***/
	
	if ( sys.useSettings['size'] ) {
		
		if ( prtcl.growthX != 0 ) {
			prtcl.scaleX += prtcl.growthX
			
			if ( sys.bSizeOscillate) {
				if ( bsign(prtcl.growthX) && prtcl.scaleX > prtcl.dthSizeX ||
				!bsign(prtcl.growthX) && prtcl.scaleX < prtcl.dthSizeX ) {
					prtcl.dthSizeX = prtcl.brtSizeX
					prtcl.brtSizeX = prtcl.scaleX
					prtcl.growthX = -prtcl.growthX
				}
			}
		} else if (prtcl.lifetime != null) {
			if (sys.bSizeOscillate) {
				if ( now < prtcl.halflife ) {
					prtcl.scaleX = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.brtSizeX, prtcl.dthSizeX )
				} else {
					prtcl.scaleX = transfer( prtcl.halflife, now, prtcl.deathtime, prtcl.dthSizeX, prtcl.brtSizeX )
				}
			} else {
				prtcl.scaleX = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtSizeX, prtcl.dthSizeX )
			}
		}
		
		if ( prtcl.growthY != 0 ) {
			prtcl.scaleY += prtcl.growthY
			
			if ( sys.bSizeOscillate) {
				if ( bsign(prtcl.growthY) && prtcl.scaleY > prtcl.dthSizeY ||
				!bsign(prtcl.growthY) && prtcl.scaleY < prtcl.dthSizeY ) {
					prtcl.dthSizeY = prtcl.brtSizeY
					prtcl.brtSizeY = prtcl.scaleY
					prtcl.growthY = -prtcl.growthY
				}
			}
		} else if (prtcl.lifetime != null) {
			if (sys.bSizeOscillate) {
				if ( now < prtcl.halflife ) {
					prtcl.scaleY = transfer( prtcl.birthtime, now, prtcl.halflife, prtcl.brtSizeY, prtcl.dthSizeY )
				} else {
					prtcl.scaleY = transfer( prtcl.halflife, now, prtcl.deathtime, prtcl.dthSizeY, prtcl.brtSizeY )
				}
			} else {
				prtcl.scaleY = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtSizeY, prtcl.dthSizeY )
			}
		}
	}
	
	
	/*** ROTATION ***/
	
	if ( sys.useSettings['rotation'] ) {
		if ( sys.bRotToVeloc ) {
			prtcl.rotation = vec2deg( prtcl.veloc.x, prtcl.veloc.y ) - sys.rotUp
		} else if (prtcl.rot == 0 && prtcl.lifetime != null) {
			prtcl.rotation = transfer( prtcl.birthtime, now, prtcl.deathtime, prtcl.brtRot, prtcl.dthRot ) - sys.rotUp
		} else {
			prtcl.rotation += prtcl.rot
			prtcl.rot /= sys.rotFric
		}
	}
}

function killParticle( prtcl ) {	
	prtcl.removeEventListener( Event.ENTER_FRAME, updateParticle )
	
	for (var n=0; n<particles.length; n++) {
		if ( particles[n] == prtcl ) {
			particles.splice( n, 1 )
			n=particles.length
		}
	}
	
	removeChild( prtcl )
	
	prtcl = null
}