/** * @class ParticleBehavior * @author senocular * @version 0.1.1 * @description Creates functions to be used for independantly moving particle movie clips. * Functions (or "behaviors" created with the ParticleBehavior class are self- * contained and are typically assigned to a particle movie clip's onEnterFrame * event handler. Particle movie clips you would create on your own * @usage See: create, multiple. */ class ParticleBehavior { /** * @method [ Behavior Generation ] * @description The following methods generate behavior functions for your particles * @usage Static * @returns behavior functions */ /** * @method create * @description Returns an instance of the behavior function specified. Each time create * is called, a new instance of the behavior specified is created with the * properties specified in the optionsObject. For those options not specified * in the optionsObject, defaults are provided * @usage
myParticle.onEnterFrame = ParticleBehavior.create("behaviorname" [, optionsObject]);
* @param behaviorname (String) The name of the behavior to be created
* @param optionsObject (String) Optional; default: behavior defaults. An object of options related to the behavior
* @returns behavior function
*/
public static function create(method, argumentsObject){
if (!ParticleBehavior[method]) return false;
return ParticleBehavior[method].apply(null, ParticleBehavior.generateArguments(method, argumentsObject));
}
/**
* @method multiple
* @description Returns an instance of a function that combines each behavior passed
* @usage myParticle.onEnterFrame = ParticleBehavior.multiple(behavior [, behavior...]);* @param behavior (Function) any number of comma separated particle behavior functions created with ParticleBehavior.create * @returns a single behavior function representing the actions of each passed */ public static function multiple(){ var i, a = arguments, n = a.length; return function(){ for(i=0;i
ParticleBehavior.create("slide", {xvelocity:1, xincrease:1, xfriction:.9});
* @param xvelocity (Number) Optional; default: 0. Horizontal velocity or the amount added to the behavior owner's _x property each time the behavior is called
* @param yvelocity (Number) Optional; default: 0. Vertical velocity or the amount added to the behavior owner's _y property each time the behavior is called
* @param xincrease (Number) Optional; default: 0. The amount added to the xvelocity each time the behavior is called
* @param yincrease (Number) Optional; default: 0. The amount added to the yvelocity each time the behavior is called
* @param xfriction (Number) Optional; default: 1. The amount multiplied to the xvelocity each time the behavior is called
* @param yfriction (Number) Optional; default: 1. The amount multiplied to the yvelocity each time the behavior is called
* @param gravity (Number) Optional; default: 0. Gravity property representing the amount added to the yvelocity each time the behavior is called
* @returns behavior function.
*/
private static function slide(vx, vy, cx, cy, fx, fy, g){
if (g) cy += g;
return function(){
this._x += vx = (vx + cx) * fx;
this._y += vy = (vy + cy) * fy;
}
}
/**
* @method bounce
* @description Bouncing motion behavior (2D). Moves a movie clip in any direction with a speed
* based on xvelocity and yvelocity. Each frame the velocities increase by x and y
* increases (yvelocity is also increased by gravity) through an additive
* process and are further affected by friction through a multiplication. When the
* movie clip reaches the bounds, velocity is reversed creating a bounce.
* @usage ParticleBehavior.create("bounce", {xvelocity:20, yvelocity:2, xfriction:.8, bounds:myClip.getBounds()});
* @param xvelocity (Number) Optional; default: 0. Horizontal velocity or the amount added to the behavior owner's _x property each time the behavior is called
* @param yvelocity (Number) Optional; default: 0. Vertical velocity or the amount added to the behavior owner's _y property each time the behavior is called
* @param xincrease (Number) Optional; default: 0. The amount added to the xvelocity each time the behavior is called
* @param yincrease (Number) Optional; default: 0. The amount added to the yvelocity each time the behavior is called
* @param xfriction (Number) Optional; default: 1. The amount multiplied to the xvelocity each time the behavior is called
* @param yfriction (Number) Optional; default: 1. The amount multiplied to the yvelocity each time the behavior is called
* @param gravity (Number) Optional; default: 0. Gravity property representing the amount added to the yvelocity each time the behavior is called
* @param bounds (Object) Optional; default: bounds of Stage. A bounds object (as given by getBounds) representing the area in which the movie clip will bounce
* @returns behavior function.
*/
private static function bounce(vx, vy, cx, cy, fx, fy, g, b){
var l = b.xMin;
var t = b.yMin;
var r = b.xMax;
b = b.yMax;
if (g) cy += g;
return function(){
this._x += vx = (vx + cx) * fx;
this._y += vy = (vy + cy) * fy;
if (this._x <= l){
this._x = l;
vx = Math.abs(vx);
}else if (this._x >= r){
this._x = r;
vx = -Math.abs(vx);
}
if (this._y <= t){
this._y = t;
vy = Math.abs(vy);
}else if (this._y >= b){
this._y = b;
vy = -Math.abs(vy);
}
}
}
/**
* @method bounce3D
* @description Bouncing motion behavior (3D). Moves a movie clip in any direction with a speed
* based on xvelocity, yvelocity and zvelocity within 3D space. Each frame the velocities
* increase by x, y, and z increases (yvelocity is also increased by gravity) through an additive
* process and are further affected by friction through a multiplication. When the
* movie clip reaches the bounds, velocity is reversed creating a bounce.
* @usage ParticleBehavior.create("bounce3D", {xvelocity:1, yvelocity:10, swap:true});
* @param xvelocity (Number) Optional; default: 0. Horizontal velocity or the amount added to the behavior owner's x position in 3D space each time the behavior is called
* @param yvelocity (Number) Optional; default: 0. Vertical velocity or the amount added to the behavior owner's y position in 3D space each time the behavior is called
* @param zvelocity (Number) Optional; default: 0. Forward velocity or the amount added to the behavior owner's z position in 3D space each time the behavior is called
* @param xincrease (Number) Optional; default: 0. The amount added to the xvelocity each time the behavior is called
* @param yincrease (Number) Optional; default: 0. The amount added to the yvelocity each time the behavior is called
* @param zincrease (Number) Optional; default: 0. The amount added to the zvelocity each time the behavior is called
* @param xfriction (Number) Optional; default: 1. The amount multiplied to the xvelocity each time the behavior is called
* @param yfriction (Number) Optional; default: 1. The amount multiplied to the yvelocity each time the behavior is called
* @param zfriction (Number) Optional; default: 1. The amount multiplied to the zvelocity each time the behavior is called
* @param gravity (Number) Optional; default: 0. Gravity property representing the amount added to the yvelocity each time the behavior is called
* @param bounds (Object) Optional; default: infinity except 0 for minimum y. A bounds object (as given by getBounds) with additional zMin and zMax properties representing the area in which the movie clip will bounce in 3D space
* @param focallength (Number) Optional; default: 300. The focal length to be applied to the 3D view of particles
* @param swap (Boolean) Optional; default: false. Determines whether or not swapDepths is used to control the arrangement of movie clips using this behavior in the 3D space
* @returns behavior function.
*/
private static function bounce3D(x, y, z, vx, vy, vz, cx, cy, cz, fx, fy, fz, g, b, fl, w){
var l = b.xMin;
var r = b.xMax;
var f = b.zMax;
var k = b.zMin;
var t = b.yMax;
b = b.yMin;
if (g) cy -= g;
var s;
return function(){
x += vx = (vx + cx) * vx;
y += vy = (vy + cy) * vy;
z += vz = (vz + cz) * vz;
if (x <= l){
x = l;
vx = Math.abs(vx);
}else if (x >= r){
x = r;
vx = -Math.abs(vx);
}
if (y <= b){
y = b;
vy = Math.abs(vy);
}else if (y >= t){
y = t;
vy = -Math.abs(vy);
}
if (z <= k){
z = k;
vz = Math.abs(vz);
}else if (z >= f){
z = f;
vz = -Math.abs(vz);
}
s = fl/(fl + z);
this._xscale = this._yscale = 100*s;
this._x = x*s;
this._y = -y*s;
if (w) this.swapDepths(Math.round(s*1000));
}
}
/**
* @method size
* @description Sizing behavior. Scales a movie clip.
* @usage ParticleBehavior.create("size", {xincrease:2, yincrease:2, use:"value"});
* @param xincrease (Number) Optional; default: 0. Amount of increase for sizing the movie clip along its local x axis
* @param yincrease (Number) Optional; default: 0. Amount of increase for sizing the movie clip along its local y axis
* @param use (String) Optional; values: "percent", "value"; default: "percent". Determines whether the movie clip is scaled through percent ("percent") or through added numeric values ("value"). If not "percent", "value" is implied
* @returns behavior function
*/
private static function size(xs, ys, c){
c = (c != "percent");
var r;
return function(){
if (c){
if (r = this._rotation) this._rotation = 0;
this._width += xs;
this._height += ys;
if (r) this._rotation = r;
}else{
this._xscale += xs;
this._yscale += ys;
}
}
}
/**
* @method transparency
* @description Transparency behavior. Fades a movie clip.
* @usage ParticleBehavior.create("transparency", {increase:-5});
* @param increase (Number) Optional; default: 1. Gravity property representing the amount added to the velocity each time the behavior is called
* @param use (String) Optional; values: "percent", "value"; default: "percent". Determines whether the movie clip is scaled through percent ("percent") or through added numeric values ("value"). If not "percent", "value" is implied
* @returns behavior function
*/
private static function transparency(t){
var a;
return function(){
if (a == undefined) a = this._alpha;
this._alpha = a += t;
}
}
/**
* @method repel
* @description Repelling motion behavior. Creates a behavior that causes a movie clip to repel
* from a central location when a "repeller" (either the mouse or a movie clip) approches
* @usage ParticleBehavior.create("repel", {x:100, y:100, repeller:my_mc});
* @param x (Number) Optional; default: current _x location. The origin x from which the movie clip is based and is repelled from
* @param y (Number) Optional; default: current _y location. The origin y from which the movie clip is based and is repelled from
* @param repeller (MovieClip, Mouse) Optional; default: Mouse. Object from which the clip is repelled. If not a MovieClip, then Mouse can be specified to be repelled from the mouse
* @param range (Number) Optional; default: 100. The range a which the repeller starts to repel the movie clip from it's origin
* @param acceleration (Number) Optional; default: .03. Acceleration factor for repelling movement
* @param friction (Number) Optional; default: .9. Friction factor for repelling movement
* @returns behavior function
*/
private static function repel (x, y, o, r, a, f) {
var d,dx,dy,vx,vy,v;
return function(){
if (x == undefined) x = this._x;
if (y == undefined) y = this._y;
if (o == Mouse){
dx = this._parent._xmouse - this._x;
dy = this._parent._ymouse - this._y;
}else{
dx = o._x - this._x;
dy = o._y - this._y;
}
d = Math.sqrt(dx*dx + dy*dy);
if (d < r) {
var v = d*r*a;
if (v != 0){
vx -= dx/v;
vy -= dy/v;
}
}
this._x += (vx = (vx + (x - this._x)*a)*f);
this._y += (vy = (vy + (y - this._y)*a)*f);
}
}
/**
* @method avoid
* @description Avoiding motion behavior. Creates a behavior that causes a movie clip to avoid
* a movie clip or the mouse.
* @usage ParticleBehavior.create("avoid", {velocity:2, range:50, avoid:my_mc});
* @param avoid (MovieClip, Mouse) Optional; default: Mouse. Object the clip is to avoid. If not a MovieClip, then Mouse can be specified to be avoided
* @param range (Number) Optional; default: 100. The range a which the movie clip starts to avoid the avoid object
* @param velocity (Number) Optional; default: 1. Speed at which the movie clip avoids the avoid object. When acceleration is involved, this is a max speed.
* @param acceleration (Number) Optional; default: 0. Acceleration factor for avoiding movement
* @param friction (Number) Optional; default: 0. Friction factor for avoiding movement
* @returns behavior function
*/
private static function avoid(o, r, v, a, f){
var d,dx,dy,vx=0,vy=0,t,tv=0;
return function(){
if (o == Mouse){
dx = this._parent._xmouse - this._x;
dy = this._parent._ymouse - this._y;
}else{
dx = o._x - this._x;
dy = o._y - this._y;
}
d = Math.sqrt(dx*dx + dy*dy);
if (d < r) {
if (a && d) tv = Math.min(v, a*r/d);
else tv = v;
if (f) tv *= f;
t = Math.atan2(dy, dx);
vx = Math.cos(t);
vy = Math.sin(t);
}else if (f) tv *= f;
else tv = 0;
if (tv){
this._x -= vx*tv;
this._y -= vy*tv;
}
}
}
/**
* @method constrain
* @description Constraining behavior. Constrains a movieclip within a boundary.
* @usage ParticleBehavior.create("constrain", {bounds:my_mc.getBounds(), use:"bounds"});
* @param bounds (Object) Optional; default: bounds of Stage. A bounds object (as given by getBounds) representing the area in which the movie clip will be constrained
* @param check (String) Optional; values: "bounds", "center"; default: "bounds". Determines what part of the movie clip is to be checked when constraining, the movie clip's bounds ("bounds") or its center point ("center"). If not "bounds", "center" is implied
* @returns behavior function
*/
private static function constrain(b, c){
var l = b.xMin;
var t = b.yMin;
var r = b.xMax;
b = b.yMax;
c = (c != "bounds");
var pb;
return function(){
if (c){
if (this._x < l) this._x = l;
else if (this._x > r) this._x = r;
if (this._y < t) this._y = t;
else if (this._y > b) this._y = b;
}else{
pb = this.getBounds(this._parent);
if (pb.xMin < l) this._x = l - (pb.xMin - this._x);
else if (pb.xMax > r) this._x = r - (pb.xMax - this._x);
if (pb.yMin < t) this._y = t - (pb.yMin - this._y);
else if (pb.yMax > b) this._y = b - (pb.yMax - this._y);
}
}
}
/**
* @method [ Removal Behaviors ]
* @description The following behaviors are used to remove particles
* @usage Created through create or multiple
* @returns behavior functions
*/
/**
* @method boundsRemove
* @description Removal behavior. Removes a movie clip if it is no longer within the specified bounds.
* @usage ParticleBehavior.create("boundsRemove", {bounds:my_mc.getBounds(), use:"bounds"});
* @param bounds (Object) Optional; default: bounds of Stage. A bounds object (as given by getBounds) representing the area in which the movie clip will be constrained
* @param check (String) Optional; values: "bounds", "center"; default: "bounds". Determines what part of the movie clip is to be checked when constraining, the movie clip's bounds ("bounds") or its center point ("center"). If not "bounds", "center" is implied
* @returns behavior function
*/
private static function boundsRemove(b, c){
var l = b.xMin;
var t = b.yMin;
var r = b.xMax;
b = b.yMax;
c = (c != "bounds");
var pb;
return function(){
if (c){
if (this._x < l || this._x > r || this._y < t || this._y > b) this.removeMovieClip();
}else{
pb = this.getBounds(this._parent);
if (pb.xMax < l || pb.xMin > r || pb.yMax < t || pb.yMin > b) this.removeMovieClip();
}
}
}
/**
* @method timedRemove
* @description Removal behavior. Removes a movie clip after a specified time (ms).
* @usage ParticleBehavior.create("timedRemove", {time:3000});
* @param time (Number) Optional; default: 1000. Time in milliseconds to wait before removing the clip. Removal will only occur when the behavior is called
* @returns behavior function
*/
private static function timedRemove(t){
var s = getTimer();
return function(){
if ((getTimer()-s) >= t) this.removeMovieClip();
}
}
/**
* @method framesRemove
* @description Removal behavior. Removes a movie clip after a specified frames.
* @usage ParticleBehavior.create("framesRemove", {frames:60});
* @param frames (Number) Optional; default: 100. Number of frames to wait before removing the clip. Removal will only occur when the behavior is called
* @returns behavior function
*/
private static function framesRemove(f){
var e = 0;
return function(){
if ((++e) >= f) this.removeMovieClip();
}
}
/**
* @method changeInPositionRemove
* @description Removal behavior. Removes a movie clip after a specified frames.
* @usage ParticleBehavior.create("changeInPositionRemove", {distance:100, check:"less"});
* @param distance (Number) Optional; default: 10. Distance to check between the current location and the last recorded location
* @param check (String) Optional; values: "greater", "less"; default: "greater". Determines whether distance is checked to be greater than or less than the specified distance for removal. If not "greater", "less" is implied
* @returns behavior function
*/
private static function changeInPositionRemove(d, c){
var d = d*d;
var x,y,dx,dy;
c = (c != "greater");
return function(){
if (x != undefined){
dx = x - this._x;
dy = y - this._y;
if (c){
if (d >= (dx*dx + dy*dy)) this.removeMovieClip();
}else{
if (d <= (dx*dx + dy*dy)) this.removeMovieClip();
}
}
x = this._x;
y = this._y;
}
}
/**
* @method distanceRemove
* @description Removal behavior. Removes a movie clip after its a certain distance from a point.
* @usage ParticleBehavior.create("distanceRemove", {x:50, y75, distance:50});
* @param x (Number) Optional; default: current _x location. The origin x from which distance is to be checked
* @param y (Number) Optional; default: current _y location. The origin y from which distance is to be checked
* @param distance (Number) Optional; default: 100. Distance to check between the current location and the last recorded location
* @returns behavior function
*/
private static function distanceRemove(x, y, d){
var d = d*d;
var dx,dy;
return function(){
if (x == undefined) x = this._x;
if (y == undefined) y = this._y;
dx = x - this._x;
dy = y - this._y;
if (d >= (dx*dx + dy*dy)) this.removeMovieClip();
}
}
/**
* @method distanceTraveledRemove
* @description Removal behavior. Removes a movie clip after it has traveled a certain distance.
* @usage ParticleBehavior.create("distanceTraveledRemove", {distance:600});
* @param distance (Number) Optional; default: 100. Distance traveled before removal
* @returns behavior function
*/
private static function distanceTraveledRemove(d){
var d = d*d;
var x,y,dx,dy,dt=0;
return function(){
if (x != undefined){
dx = x - this._x;
dy = y - this._y;
dt += (dx*dx + dy*dy);
if (d >= dt) this.removeMovieClip();
}
x = this._x;
y = this._y;
}
}
/**
* @method sizeRemove
* @description Removal behavior. Removes a movie clip after it reaches a certain size. Size is based on local coordinate space
* @usage ParticleBehavior.create("sizeRemove", {distance:600});
* @param minwidth (Number) Optional; default: 1. The minimum width the movie clip can reach before removal
* @param minheight (Number) Optional; default: 1. The minimum height the movie clip can reach before removal
* @param maxwidth (Number) Optional; default: 100. The maximum width the movie clip can reach before removal
* @param maxheight (Number) Optional; default: 100. The maximum height the movie clip can reach before removal
* @param check (String) Optional; values: "both", "single"; default: "both". Determines whether or not both height and width are checked for removal. If not "both", "single" is implied
* @returns behavior function
*/
private static function sizeRemove(nw, nh, xw, xh, c){
c = (c != "both");
var r;
return function(){
if (r = this._rotation) this._rotation = 0;
if (c){
if (nw && nw > this._width) this.removeMovieClip();
if (nh && nh > this._height) this.removeMovieClip();
if (xw && xw < this._width) this.removeMovieClip();
if (xh && xh < this._height) this.removeMovieClip();
}else{
if (nw && nh && nw > this._width && nh > this._height) this.removeMovieClip();
if (xw && xh && xw < this._width && xh < this._height) this.removeMovieClip();
}
if (r) this._rotation = r;
}
}
/* DFAULTS */
private static function generateDefaults(){
fall.defaults = [
{param:"gravity", value:1},
{param:"yvelocity", value:0}
];
slide.defaults = [
{param:"xvelocity", value:0},
{param:"yvelocity", value:0},
{param:"xincrease", value:0},
{param:"yincrease", value:0},
{param:"xfriction", value:1},
{param:"yfriction", value:1},
{param:"gravity", value:0}
];
bounce.defaults = [
{param:"xvelocity", value:0},
{param:"yvelocity", value:0},
{param:"xincrease", value:0},
{param:"yincrease", value:0},
{param:"xfriction", value:1},
{param:"yfriction", value:1},
{param:"gravity", value:0},
{param:"bounds", value:{xMin: 0, yMin: 0, xMax: Stage.width, yMax: Stage.height}}
];
bounce3D.defaults = [
{param:"x", value:0},
{param:"y", value:0},
{param:"z", value:0},
{param:"xvelocity", value:0},
{param:"yvelocity", value:0},
{param:"zvelocity", value:0},
{param:"xincrease", value:0},
{param:"yincrease", value:0},
{param:"zincrease", value:0},
{param:"xfriction", value:0},
{param:"yfriction", value:0},
{param:"zfriction", value:0},
{param:"gravity", value:0},
{param:"bounds", value:{
xMin:Number.NEGATIVE_INFINITY, yMin:0, zMin:Number.NEGATIVE_INFINITY,
xMax:Number.POSITIVE_INFINITY, yMax:Number.POSITIVE_INFINITY, zMax:Number.POSITIVE_INFINITY
}
},
{param:"focallength", value:300},
{param:"swap", value:false}
];
size.defaults = [
{param:"xincrease", value:0},
{param:"yincrease", value:0},
{param:"use", value:"percent"} /* "percent" or "value", "value" implied if not "percent" */
];
transparency.defaults = [
{param:"increase", value:0}
];
repel.defaults = [
{param:"x", value:undefined},
{param:"y", value:undefined},
{param:"repeller", value:Mouse},
{param:"range", value:100},
{param:"acceleration", value:.03},
{param:"friction", value:.9}
];
avoid.defaults = [
{param:"avoid", value:Mouse},
{param:"range", value:100},
{param:"velocity", value:1},
{param:"acceleration", value:0},
{param:"friction", value:0}
];
constrain.defaults = [
{param:"bounds", value:{xMin: 0, yMin: 0, xMax: Stage.width, yMax: Stage.height}},
{param:"check", value:"bounds"} /* "bounds" or "center", "center" implied if not "bounds" */
];
boundsRemove.defaults = [
{param:"bounds", value:{xMin: 0, yMin: 0, xMax: Stage.width, yMax: Stage.height}},
{param:"check", value:"bounds"} /* "bounds" or "center", "center" implied if not "bounds" */
];
timedRemove.defaults = [
{param:"time", value:1000}
];
framesRemove.defaults = [
{param:"frames", value:100}
];
changeInPositionRemove.defaults = [
{param:"distance", value:10},
{param:"check", value:"greater"} /* "greater" or "less", "less" implied if not "greater" */
];
distanceRemove.defaults = [
{param:"x", value:undefined},
{param:"y", value:undefined},
{param:"distance", value:100}
];
distanceTraveledRemove.defaults = [
{param:"distance", value:100}
];
sizeRemove.defaults = [
{param:"minwidth", value:1},
{param:"minheight", value:1},
{param:"maxwidth", value:100},
{param:"maxheight", value:100},
{param:"check", value:"both"} /* "both" or "single", "single" implied if not "both" */
];
return true;
}
private static var $defaults = generateDefaults();
}