Iavra

Particle Engine - Behaviours

Jan 28th, 2016 (edited)
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*:
  2.  * @plugindesc v1.00 Extension, that comes with predefined behaviours to be used with the particle engine.
  3.  * @author Iavra
  4.  *
  5.  * @help
  6.  * To use one of the behaviours included in this plugin, provide it as an argument to the "addBehaviour" function of
  7.  * your created emitter:
  8.  *
  9.  * emitter.addBehaviour(new IAVRA.PARTICLE.B.Life(200));
  10.  *
  11.  * This example will register a "Life" behaviour, that will cause particles to die after 200 frames.
  12.  *
  13.  * The following behaviours are contained in the IAVRA.PARTICLE.B / IAVRA.PARTICLE.BEHAVIOUR namespace:
  14.  *
  15.  * BindToMap(offset)                          Moves the emitter and all of its particles with the map.
  16.  *
  17.  * BindToPlayer(offset)                       Moves the emitter and all of its particles with the player.
  18.  *
  19.  * BindToEvent(id, offset)                    Moves the emitter and all of its particles with the given event.
  20.  *
  21.  * Position(zone)                             Sets the starting position of created particles to a random point inside
  22.  *                                            the given zone.
  23.  *
  24.  * Radius(radius)                             Sets the collision radius of created particles to the given value.
  25.  *                                            Behaviours using this property need to make sure to factor in the
  26.  *                                            particle's scale as well.
  27.  *
  28.  * Image(image, scaling)                      Sets the texture to be displayed by created particles. Can be overloaded
  29.  *                                            by specifying multiple images and will pick one of them at random.
  30.  *
  31.  * Velocity(x, y)                             Increases the starting velocity of created particles by the given amount.
  32.  *                                            Can be overloaded to randomize the actual values.
  33.  *
  34.  * PolarVelocity(radius, angle)               Increases the starting velocity of created particles by a vector
  35.  *                                            calculated from the given radius and angle. Can be overloaded to randomize
  36.  *                                            the actual values.
  37.  *
  38.  * Blend(mode)                                Sets the blend mode of created particles. PIXI.blendModes features a full
  39.  *                                            list of all available modes. Support variies between renderers.
  40.  *
  41.  * Life(life, easing)                         Sets the particle's life to the given value. Can be overloaded to
  42.  *                                            randomize the actual values. Also, will set the particle's energy
  43.  *                                            according to its life and age.
  44.  *
  45.  * Scale(startScale, endScale)                Transitions the particle's scale between the given start and end values.
  46.  *
  47.  * Alpha(startAlpha, endAlpha)                Transitions the particle's alpha value between the given start and end
  48.  *                                            values.
  49.  *
  50.  * Rotation(startAngle, endAngle)             Transitions the particle's rotation between the given start and end
  51.  *                                            values.
  52.  *
  53.  * Color(startColor, endColor)                Transitions the particle's tinting color between the given start and end
  54.  *                                            values.
  55.  *
  56.  * Friction(friction)                         Applies linear friction to particles, causing them to slow down over time.
  57.  *
  58.  * Force(x, y)                                Applies a linear force to particles.
  59.  *
  60.  * PolarForce(radius, angle)                  Applies a linear force to particles, that gets calculated from a polar
  61.  *                                            vector.
  62.  *
  63.  * RandomDrift(x, y)                          Randomly accelerates particles.
  64.  *
  65.  * SpeedLimit(min, max)                       Limits the velocity of particles to a given range.
  66.  *
  67.  * Attraction(center, force, epsilon)         Places a gravity well at a given point, that will attract particles
  68.  *                                            depending on their distance.
  69.  *
  70.  * Repulsion(center, force, epsilon)          Places an anti-gravity well at a given point, that will repel particles
  71.  *                                            depending on their distance.
  72.  *
  73.  * RotateToDirection()                        Rotates particles to always face in the direction, they are moving to.
  74.  *
  75.  * Collision(bounce)                          Applies collision between all particles of the emitter, depending on
  76.  *                                            their radius and scale.
  77.  *
  78.  * BoundingBox(x, y, width, height, bounce)   Restricts particles to a bounding box, causing them to bounce back, if
  79.  *                                            they try to leave it. Particles should spawn inside the box, to prevent
  80.  *                                            unpredictable side effects.
  81.  *
  82.  * WrapAroundBox(x, y, width, height)         Restricts particles to a bounding box, causing them to wrap around to the
  83.  *                                            other side, if they try to leave it. Particles should spawn inside the
  84.  *                                            box, to prevent unpredictable side effects.
  85.  *
  86.  * CollisionZone(zone, bounce)                Applies collision between particles and the given zone, both from the
  87.  *                                            inside and outside.
  88.  *
  89.  * DeathZone(zone, killOutside)               Destroys all particles in- or outside the given zone.
  90.  */
  91.  
  92. (function($, undefined) {
  93.     "use strict";
  94.  
  95.     if(!$.PARTICLE) { throw new Error("This plugin depends on 'Iavra Particle - Core'."); }
  96.  
  97.     /**
  98.      * Extends a given object with all properties from another given object. Mainly used to simplify subclassing.
  99.      * @param {Object} base - Base object to be extended.
  100.      * @param {Object} extend - Object containing the properties to be appended to the given base object.
  101.      * @returns {Object} The base object, after it has been extended.
  102.      */
  103.     var _extend = function(base, extend) {
  104.         for(var key in extend) { base[key] = extend[key]; }
  105.         return base;
  106.     };
  107.  
  108.     /**
  109.      * Returns a random floating point number between the given minimum (inclusive) and maximum (exclusive).
  110.      * @param {number} min - Minimum number to be generated (inclusive).
  111.      * @param {number} max - Maximum number to be generated (exclusive).
  112.      * @returns {number} A random number between the given minimum and maximum numbers.
  113.      */
  114.     var _random = function(min, max) {
  115.         return min + (max - min) * Math.random();
  116.     };
  117.  
  118.     /**
  119.      * Returns the given value or, if it's not defined, the default value.
  120.      * @param {*} value - Value to test.
  121.      * @param {*} defaultValue - Value to be returned, if the tested value is undefined.
  122.      * @param {*} Either the given value or defaultValue, of the former one is undefined.
  123.      */
  124.     var _default = function(value, defaultValue) {
  125.         return value === undefined ? defaultValue : value;
  126.     };
  127.  
  128.     /**
  129.      * Converts a given angle from its degree to radian representation.
  130.      * @param {number} deg - An angle, in degree.
  131.      * @returns {number} The given angle's radian representation.
  132.      */
  133.     var _degToRad = function(deg) {
  134.         return deg * Math.PI / 180;
  135.     };
  136.  
  137.     /**
  138.      * Constructs a polar vector with the given radius and angle (in radians) and returns its cartesian representation.
  139.      * @param {number} radius - Radius component of the polar vector, which defines the resulting vector's length.
  140.      * @param {number} angle - Angle component of the polar vector, in radians.
  141.      * @returns {number[]} An array containing the cartesian representation of the polar vector.
  142.      */
  143.     var _polarVector = function(radius, angle) {
  144.         return [radius * Math.cos(angle), -radius * Math.sin(angle)]
  145.     };
  146.  
  147.     //=============================================================================
  148.     // IAVRA.PARTICLE.BEHAVIOUR
  149.     //=============================================================================
  150.  
  151.     $.PARTICLE.BEHAVIOUR = $.PARTICLE.B = {
  152.  
  153.         // activities only
  154.         BindToMap: function(offset) { this._initialize(offset); },
  155.         BindToPlayer: function(offset) { this._initialize(offset); },
  156.         BindToEvent: function(id, offset) { this._initialize(id, offset); },
  157.  
  158.         // setup only
  159.         Position: function(zone) { this._initialize(zone); },
  160.         Radius: function(radius) { this._initialize(radius); },
  161.         Image: function(image, scaling) { this._initialize(image, scaling); },
  162.         Velocity: function(x, y) { this._initialize(x, y); },
  163.         PolarVelocity: function(radius, angle) { this._initialize(radius, angle); },
  164.         Blend: function(mode) { this._initialize(mode); },
  165.  
  166.         // age-dependent
  167.         Life: function(life, easing) { this._initialize(life, easing); },
  168.         Scale: function(startScale, endScale) { this._initialize(startScale, endScale); },
  169.         Alpha: function(startAlpha, endAlpha) { this._initialize(startAlpha, endAlpha); },
  170.         Rotation: function(startAngle, endAngle) { this._initialize(startAngle, endAngle); },
  171.         Color: function(startColor, endColor) { this._initialize(startColor, endColor); },
  172.  
  173.         // permanent
  174.         Friction: function(friction) { this._initialize(friction); },
  175.         Force: function(x, y) { this._initialize(x, y); },
  176.         PolarForce: function(radius, angle) { this._initialize(radius, angle); },
  177.         RandomDrift: function(x, y) { this._initialize(x, y); },
  178.         SpeedLimit: function(min, max) { this._initialize(min, max); },
  179.         Attraction: function(center, force, epsilon) { this._initialize(center, force, epsilon); },
  180.         Repulsion: function(center, force, epsilon) { this._initialize(center, force, epsilon); },
  181.         RotateToDirection: function() {},
  182.         Collision: function(bounce) { this._initialize(bounce); },
  183.         BoundingBox: function(x, y, width, height, bounce) { this._initialize(x, y, width, height, bounce); },
  184.         WrapAroundBox: function(x, y, width, height) { this._initialize(x, y, width, height); },
  185.         CollisionZone: function(zone, bounce) { this._initialize(zone, bounce); },
  186.         DeathZone: function(zone, outside) { this._initialize(zone, outside); }
  187.  
  188.     };
  189.  
  190.     //=============================================================================
  191.     // IAVRA.PARTICLE.BEHAVIOUR.BindToMap
  192.     //=============================================================================
  193.  
  194.     /**
  195.      * Moves the emitter and all of its particles with the map.
  196.      */
  197.     $.PARTICLE.BEHAVIOUR.BindToMap.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  198.  
  199.         /**
  200.          * Initializes the behaviour. The given offset is added to the adjusted emitter position.
  201.          * @param {PIXI.Point} [offset] - Positional offset relative to the map's upper left corner.
  202.          */
  203.         _initialize: function(offset) {
  204.             this._offset = offset || new PIXI.Point();
  205.         },
  206.  
  207.         /**
  208.          * Gets called on every update cycle, before particles are updated. Sets the particle's position relative to
  209.          * the current map position.
  210.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing this behaviour.
  211.          */
  212.         activity: function(emitter) {
  213.             emitter.position.x = this._offset.x + $gameMap.adjustX(0) * $gameMap.tileWidth();
  214.             emitter.position.y = this._offset.y + $gameMap.adjustY(0) * $gameMap.tileHeight();
  215.         }
  216.  
  217.     });
  218.  
  219.     //=============================================================================
  220.     // IAVRA.PARTICLE.BEHAVIOUR.BindToPlayer
  221.     //=============================================================================
  222.  
  223.     /**
  224.      * Moves the emitter and all of its particles with the player.
  225.      */
  226.     $.PARTICLE.BEHAVIOUR.BindToPlayer.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  227.  
  228.         /**
  229.          * Initializes the behaviour. The given offset is added to the adjusted emitter position.
  230.          * @param {PIXI.Point} [offset] - Positional offset relative to the player position's center.
  231.          */
  232.         _initialize: function(offset) {
  233.             this._offset = offset || new PIXI.Point();
  234.         },
  235.  
  236.         /**
  237.          * Gets called on every update cycle, before particles are updated. Sets the particle's position relative to
  238.          * the player's position.
  239.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing this behaviour.
  240.          */
  241.         activity: function(emitter) {
  242.             var player = $gamePlayer;
  243.             emitter.position.x = this._offset.x + $gameMap.adjustX(player._realX + 0.5) * $gameMap.tileWidth();
  244.             emitter.position.y = this._offset.y + $gameMap.adjustY(player._realY + 0.5) * $gameMap.tileHeight();
  245.         }
  246.  
  247.     });
  248.  
  249.     //=============================================================================
  250.     // IAVRA.PARTICLE.BEHAVIOUR.BindToEvent
  251.     //=============================================================================
  252.  
  253.     /**
  254.      * Moves the emitter and all of its particles with the given event
  255.      */
  256.     $.PARTICLE.BEHAVIOUR.BindToEvent.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  257.  
  258.         /**
  259.          * Initializes the behaviour. The given offset is added to the adjusted emitter position.
  260.          * @param {number} id - Id of the event to be tracked.
  261.          * @param {PIXI.Point} [offset] - Positional offset relative to the event position's center.
  262.          */
  263.         _initialize: function(id, offset) {
  264.             this._id = id;
  265.             this._offset = offset || new PIXI.Point();
  266.         },
  267.  
  268.         /**
  269.          * Gets called on every update cycle, before particles are updated. Sets the particle's position relative to
  270.          * the given event's position.
  271.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing this behaviour.
  272.          */
  273.         activity: function(emitter) {
  274.             var event = $gameMap.event(this._id);
  275.             emitter.position.x = this._offset.x + $gameMap.adjustX(event._realX + 0.5) * $gameMap.tileWidth();
  276.             emitter.position.y = this._offset.y + $gameMap.adjustY(event._realY + 0.5) * $gameMap.tileHeight();
  277.         }
  278.  
  279.     });
  280.  
  281.     //=============================================================================
  282.     // IAVRA.PARTICLE.BEHAVIOUR.Position
  283.     //=============================================================================
  284.  
  285.     /**
  286.      * Sets the starting position of created particles to a random point inside the given zone.
  287.      */
  288.     $.PARTICLE.BEHAVIOUR.Position.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  289.  
  290.         /**
  291.          * Initializes the behaviour. The given zone will be used to pick a random point as a starting position.
  292.          * @param {IAVRA.PARTICLE.Zone} zone - Zone instance to be used to pick a random point inside it.
  293.          */
  294.         _initialize: function(zone) {
  295.             this._zone = zone;
  296.         },
  297.  
  298.         /**
  299.          * Gets called, whenever a new particle is created. Sets the particle's position (and oldPosition, to stay
  300.          * compatible with other behaviours) to a random point inside the given zone.
  301.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  302.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  303.          */
  304.         setup: function(emitter, particle) {
  305.             var point = this._zone.getPoint();
  306.             particle.oldPosition.x = particle.position.x = point.x;
  307.             particle.oldPosition.y = particle.position.y = point.y;
  308.         }
  309.  
  310.     });
  311.  
  312.     //=============================================================================
  313.     // IAVRA.PARTICLE.BEHAVIOUR.Radius
  314.     //=============================================================================
  315.  
  316.     /**
  317.      * Sets the collision radius of created particles to the given value. Behaviours using this property need to make
  318.      * sure to factor in the particle's scale as well.
  319.      */
  320.     $.PARTICLE.BEHAVIOUR.Radius.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  321.  
  322.         /**
  323.          * Initializes the behaviour.
  324.          * @param {number} radius - Base collision radius to be used by created particles.
  325.          */
  326.         _initialize: function(radius) {
  327.             this._radius = radius;
  328.         },
  329.  
  330.         /**
  331.          * Gets called, whenever a new particle is created. Sets the particle's collision radius to the given value.
  332.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  333.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  334.          */
  335.         setup: function(emitter, particle) {
  336.             particle.radius = this._radius;
  337.         }
  338.  
  339.     });
  340.  
  341.     //=============================================================================
  342.     // IAVRA.PARTICLE.BEHAVIOUR.Image
  343.     //=============================================================================
  344.  
  345.     /**
  346.      * Sets the texture to be displayed by created particles. Can be overloaded by specifying multiple images and will
  347.      * pick one of them at random.
  348.      */
  349.     $.PARTICLE.BEHAVIOUR.Image.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  350.  
  351.         /**
  352.          * Initializes the behaviour. Can either be called with a single image or an array of images, in which case
  353.          * particles will be assigned one of them at random.
  354.          * @param {(string|string[])} image - Path to an image file or an array of images to be used.
  355.          * @param {number} [scaling=PIXI.scaleModes.DEFAULT] scaling - Scale mode to be used. Possible values are 0
  356.          * (linear) and 1 (nearest). Defaults to 0.
  357.          */
  358.         _initialize: function(image, scaling) {
  359.             this._images = [];
  360.             if(Array.isArray(image)) {
  361.                 for(var i = 0, max = image.length; i < max; ++i) {
  362.                     this._images.push(PIXI.Texture.fromImage(image[i], null, scaling || PIXI.scaleModes.DEFAULT));
  363.                 }
  364.             } else {
  365.                 this._images.push(PIXI.Texture.fromImage(image, null, scaling || PIXI.scaleModes.DEFAULT));
  366.             }
  367.         },
  368.  
  369.         /**
  370.          * Gets called, whenever a new particle is created. Sets the particle's texture according to the given values.
  371.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  372.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  373.          */
  374.         setup: function(emitter, particle) {
  375.             particle.texture = (this._images.length === 1)
  376.                 ? this._images[0]
  377.                 : this._images[(this._images.length * Math.random())|0];
  378.         }
  379.  
  380.     });
  381.  
  382.     //=============================================================================
  383.     // IAVRA.PARTICLE.BEHAVIOUR.Velocity
  384.     //=============================================================================
  385.  
  386.     /**
  387.      * Increases the starting velocity of created particles by the given amount. Can be overloaded to randomize the
  388.      * actual values.
  389.      */
  390.     $.PARTICLE.BEHAVIOUR.Velocity.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  391.  
  392.         /**
  393.          * Initializes the behaviour. Can either be called with static numbers or arrays, in which case their contents
  394.          * will be used as the minimum and maximum bounds, when creating random numbers.
  395.          * @param {(number|numbers[])} x - Horizontal velocity or bounds for random number creation.
  396.          * @param {(number|numbers[])} y - Vertical velocity or bounds for random number creation.
  397.          */
  398.         _initialize: function(x, y) {
  399.             if(Array.isArray(x)) {
  400.                 this._minX = x[0];
  401.                 this._maxX = x[1];
  402.             } else {
  403.                 this._minX = this._maxX = x || 0;
  404.             }
  405.             if(Array.isArray(y)) {
  406.                 this._minY = y[0];
  407.                 this._maxY = y[1];
  408.             } else {
  409.                 this._minY = this._maxY = y || 0;
  410.             }
  411.         },
  412.  
  413.         /**
  414.          * Gets called, whenever a new particle is created. Increases its velocity according to the given values.
  415.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  416.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  417.          */
  418.         setup: function(emitter, particle) {
  419.             particle.velocity.x += (this._minX === this._maxX) ? this._minX : _random(this._minX, this._maxX);
  420.             particle.velocity.y += (this._minY === this._maxY) ? this._minY : _random(this._minY, this._maxY);
  421.         }
  422.  
  423.     });
  424.  
  425.     //=============================================================================
  426.     // IAVRA.PARTICLE.BEHAVIOUR.PolarVelocity
  427.     //=============================================================================
  428.  
  429.     /**
  430.      * Increases the starting velocity of created particles by a vector calculated from the given radius and angle.
  431.      * Can be overloaded to randomize the actual values.
  432.      */
  433.     $.PARTICLE.BEHAVIOUR.PolarVelocity.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  434.  
  435.         /**
  436.          * Initializes the behaviour. Can either be called with static numbers or arrays, in which case their contents
  437.          * will be used as the minimum and maximum bounds, when creating random numbers.
  438.          * @param {(number|numbers[])} radius - Radius of the polar vector or bounds for random number creation.
  439.          * @param {(number|numbers[])} angle - Angle of the polar vector or bounds for random numbers, in degree.
  440.          */
  441.         _initialize: function(radius, angle) {
  442.             if(Array.isArray(radius)) {
  443.                 this._minRadius = radius[0];
  444.                 this._maxRadius = radius[1];
  445.             } else {
  446.                 this._minRadius = this._maxRadius = radius || 0;
  447.             }
  448.             if(Array.isArray(angle)) {
  449.                 this._minAngle = _degToRad(angle[0]);
  450.                 this._maxAngle = _degToRad(angle[1]);
  451.             } else {
  452.                 this._minAngle = this._maxAngle = _degToRad(angle || 0);
  453.             }
  454.         },
  455.  
  456.         /**
  457.          * Gets called, whenever a new particle is created. Increases its velocity according to the given values.
  458.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  459.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  460.          */
  461.         setup: function(emitter, particle) {
  462.             var vector = _polarVector(
  463.                 (this._minRadius === this._maxRadius) ? this._minRadius : _random(this._minRadius, this._maxRadius),
  464.                 (this._minAngle === this._maxAngle) ? this._minAngle : _random(this._minAngle, this._maxAngle)
  465.             )
  466.             particle.velocity.x += vector[0];
  467.             particle.velocity.y += vector[1];
  468.         }
  469.  
  470.     });
  471.  
  472.     //=============================================================================
  473.     // IAVRA.PARTICLE.BEHAVIOUR.Blend
  474.     //=============================================================================
  475.  
  476.     /**
  477.      * Sets the blend mode of created particles. PIXI.blendModes features a full list of all available modes. Support
  478.      * variies between renderers.
  479.      */
  480.     $.PARTICLE.BEHAVIOUR.Blend.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  481.  
  482.         /**
  483.          * Initializes the behaviour.
  484.          * @param {number} image - Blend mode to be used.
  485.          */
  486.         _initialize: function(mode) {
  487.             this._mode = mode;
  488.         },
  489.  
  490.         /**
  491.          * Gets called, whenever a new particle is created. Sets its blend mode to the given value.
  492.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  493.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  494.          */
  495.         setup: function(emitter, particle) {
  496.             particle.blendMode = this._mode;
  497.         }
  498.  
  499.     });
  500.  
  501.     //=============================================================================
  502.     // IAVRA.PARTICLE.BEHAVIOUR.Life
  503.     //=============================================================================
  504.  
  505.     /**
  506.      * Sets the particle's life to the given value. Can be overloaded to randomize the actual values. Also, will set
  507.      * the particle's energy according to its life and age.
  508.      */
  509.     $.PARTICLE.BEHAVIOUR.Life.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  510.  
  511.         /**
  512.          * Initializes the behaviour. Can either be called with static numbers or an array, in which case its contents
  513.          * will be used as the minimum and maximum bound, when creating random numbers. An optional easing function
  514.          * can be specified to modify the particle's energy curve.
  515.          * @param {(number|numbers[])} life - Particle's life or minimum and maximum values to create random numbers.
  516.          * @param {function} [easing] - Optional easing function to calculate the particle's energy.
  517.          */
  518.         _initialize: function(life, easing) {
  519.             if(Array.isArray(life)) {
  520.                 this._min = life[0];
  521.                 this._max = life[1];
  522.             } else {
  523.                 this._min = this._max = life || 0;
  524.             }
  525.             this._easing = easing || function(k) { return k; };
  526.         },
  527.  
  528.         /**
  529.          * Gets called, whenever a new particle is created. Sets its life according to the given values.
  530.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance, that created the particle.
  531.          * @param {IAVRA.PARTICLE.Particle} particle - A new particle, that has just been created by the emitter.
  532.          */
  533.         setup: function(emitter, particle) {
  534.             particle.life = (this._min === this._max) ? this._min : _random(this._min, this._max);
  535.         },
  536.  
  537.         /**
  538.          * Gets called on every update cycle, for each particle. Calculates the particle's energy according to the
  539.          * given easing function.
  540.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  541.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  542.          * @param {number} index - The given particle's position inside the given emitter's children array.
  543.          */
  544.         update: function(emitter, particle, index) {
  545.             particle.energy = particle.dead ? 0 : 1 - this._easing(particle.age / particle.life);
  546.         }
  547.  
  548.     });
  549.  
  550.     //=============================================================================
  551.     // IAVRA.PARTICLE.BEHAVIOUR.Scale
  552.     //=============================================================================
  553.  
  554.     /**
  555.      * Transitions the particle's scale between the given start and end values.
  556.      */
  557.     $.PARTICLE.BEHAVIOUR.Scale.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  558.  
  559.         /**
  560.          * Initializes the behaviour.
  561.          * @param {number} [startScale=0] - Starting value to be used for the particle's scale.
  562.          * @param {number} [endScale] - End value to be used for the particle's scale. If this is omitted, the particle
  563.          * will have a fixed scale, instead.
  564.          */
  565.         _initialize: function(startScale, endScale) {
  566.             this._start = startScale || 0;
  567.             this._end = endScale;
  568.         },
  569.  
  570.         /**
  571.          * Gets called on every update cycle, for each particle. Sets the particle's scale according to the given
  572.          * values and its energy.
  573.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  574.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  575.          * @param {number} index - The given particle's position inside the given emitter's children array.
  576.          */
  577.         update: function(emitter, particle) {
  578.             particle.scale.x = particle.scale.y = (this._end === undefined)
  579.                 ? this._start
  580.                 : this._end + (this._start - this._end) * particle.energy;
  581.         }
  582.  
  583.     });
  584.  
  585.     //=============================================================================
  586.     // IAVRA.PARTICLE.BEHAVIOUR.Alpha
  587.     //=============================================================================
  588.  
  589.     /**
  590.      * Transitions the particle's alpha value between the given start and end values.
  591.      */
  592.     $.PARTICLE.BEHAVIOUR.Alpha.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  593.  
  594.         /**
  595.          * Initializes the behaviour.
  596.          * @param {number} [startAlpha=0] - Starting value to be used for the particle's alpha.
  597.          * @param {number} [endAlpha] - End value to be used for the particle's alpha. If this is omitted, the particle
  598.          * will have a fixed alpha value, instead.
  599.          */
  600.         _initialize: function(startAlpha, endAlpha) {
  601.             this._start = startAlpha || 0;
  602.             this._end = endAlpha;
  603.         },
  604.  
  605.         /**
  606.          * Gets called on every update cycle, for each particle. Sets the particle's alpha according to the given
  607.          * values and its energy.
  608.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  609.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  610.          * @param {number} index - The given particle's position inside the given emitter's children array.
  611.          */
  612.         update: function(emitter, particle) {
  613.             particle.alpha = (this._end === undefined)
  614.                 ? this._start
  615.                 : this._end + (this._start - this._end) * particle.energy;
  616.         }
  617.  
  618.     });
  619.  
  620.     //=============================================================================
  621.     // IAVRA.PARTICLE.BEHAVIOUR.Rotation
  622.     //=============================================================================
  623.  
  624.     /**
  625.      * Transitions the particle's rotation between the given start and end values.
  626.      */
  627.     $.PARTICLE.BEHAVIOUR.Rotation.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  628.  
  629.         /**
  630.          * Initializes the behaviour.
  631.          * @param {number} [startAngle=0] - Starting value to be used for the particle's rotation, in radians.
  632.          * @param {number} [endAngle] - End value to be used for the particle's rotation, in radians. If this is
  633.          * omitted, the particle will have a fixed rotation, instead.
  634.          */
  635.         _initialize: function(startAngle, endAngle) {
  636.             this._start = _degToRad(startAngle || 0);
  637.             if(endAngle !== undefined) { this._end = _degToRad(endAngle); }
  638.         },
  639.  
  640.         /**
  641.          * Gets called on every update cycle, for each particle. Sets the particle's rotation according to the given
  642.          * values and its energy.
  643.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  644.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  645.          * @param {number} index - The given particle's position inside the given emitter's children array.
  646.          */
  647.         update: function(emitter, particle) {
  648.             particle.rotation = (this._end === undefined)
  649.                 ? this._start
  650.                 : this._end + (this._start - this._end) * particle.energy;
  651.         }
  652.  
  653.     });
  654.  
  655.     //=============================================================================
  656.     // IAVRA.PARTICLE.BEHAVIOUR.Color
  657.     //=============================================================================
  658.  
  659.     /**
  660.      * Transitions the particle's tinting color between the given start and end values.
  661.      */
  662.     $.PARTICLE.BEHAVIOUR.Color.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  663.  
  664.         /**
  665.          * Initializes the behaviour.
  666.          * @param {number} [startColor=0] - Starting value to be used for the particle's color, as hex string.
  667.          * @param {number} [endColor] - End value to be used for the particle's color, as hex string. If this is
  668.          * omitted, the particle will have a fixed tinting color, instead.
  669.          */
  670.         _initialize: function(startColor, endColor) {
  671.             this._start = this._getRgbColor(startColor);
  672.             this._end = this._getRgbColor(endColor);
  673.         },
  674.  
  675.         /**
  676.          * Gets called on every update cycle, for each particle. Sets the particle's tint according to the given
  677.          * values and its energy.
  678.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  679.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  680.          * @param {number} index - The given particle's position inside the given emitter's children array.
  681.          */
  682.         update: function(emitter, particle, index) {
  683.             if(this._end === null) {
  684.                 particle.tint = this._getHexColor(this._start);
  685.             } else {
  686.                 var start = this._start, end = this._end, ratio = particle.energy, inverse = 1 - ratio;
  687.                 particle.tint = this._getHexColor([
  688.                     start[0] * ratio + end[0] * inverse,
  689.                     start[1] * ratio + end[1] * inverse,
  690.                     start[2] * ratio + end[2] * inverse
  691.                 ]);
  692.             }
  693.         },
  694.  
  695.         /**
  696.          * Internal utility function, that converts a given hex string to its rgb representation.
  697.          * @param {string} [color] - Hex color string to be converted.
  698.          * @returns {(number[]|null)} - An array containing the rgb values of the given color or null, if the color
  699.          * parameter was omitted.
  700.          */
  701.         _getRgbColor: function(color) {
  702.             if(color === undefined || color === null) { return null; }
  703.             color = (color.charAt(0) == '#') ? color.substring(1, 7) : color;
  704.             return [
  705.                 parseInt(color.substring(0, 2), 16),
  706.                 parseInt(color.substring(2, 4), 16),
  707.                 parseInt(color.substring(4, 6), 16)
  708.             ];
  709.         },
  710.  
  711.         /**
  712.          * Internal utility function, that converts a given rgb array to its hex number representation.
  713.          * @param {number[]} rgb - Color array to be converted.
  714.          * @returns {number} - Hex number representation of the given color.
  715.          */
  716.         _getHexColor: function(rgb) {
  717.             return ((rgb[0] << 16) + (rgb[1] << 8) + rgb[2]);
  718.         }
  719.  
  720.     });
  721.  
  722.     //=============================================================================
  723.     // IAVRA.PARTICLE.BEHAVIOUR.Friction
  724.     //=============================================================================
  725.  
  726.     /**
  727.      * Applies linear friction to particles, causing them to slow down over time.
  728.      */
  729.     $.PARTICLE.BEHAVIOUR.Friction.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  730.  
  731.         /**
  732.          * Initializes the behaviour.
  733.          * @param {number} friction - Damping value to be used. Since this is applies every frame, it's advised to use
  734.          * very low values.
  735.          */
  736.         _initialize: function(friction) {
  737.             this._friction = friction;
  738.         },
  739.  
  740.         /**
  741.          * Gets called on every update cycle, for each particle. Multiplies the particle's velocity vector with (1 -
  742.          * friction), slowing it down.
  743.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  744.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  745.          * @param {number} index - The given particle's position inside the given emitter's children array.
  746.          */
  747.         update: function(emitter, particle, index) {
  748.             var lengthSq = particle.velocity.x * particle.velocity.x + particle.velocity.y * particle.velocity.y;
  749.             if(lengthSq === 0) { return; }
  750.             var scale = 1 - this._friction / Math.sqrt(lengthSq);
  751.             if(scale <= 0) {
  752.                 particle.velocity.x = particle.velocity.y = 0;
  753.             } else {
  754.                 particle.velocity.x *= scale;
  755.                 particle.velocity.y *= scale;
  756.             }
  757.         }
  758.  
  759.     });
  760.  
  761.     //=============================================================================
  762.     // IAVRA.PARTICLE.BEHAVIOUR.Force
  763.     //=============================================================================
  764.  
  765.     /**
  766.      * Applies a linear force to particles.
  767.      */
  768.     $.PARTICLE.BEHAVIOUR.Force.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  769.  
  770.         /**
  771.          * Initializes the behaviour.
  772.          * @param {number} [x=0] - X component of the force vector to apply.
  773.          * @param {number} [y=0] - Y component of the force vector to apply.
  774.          */
  775.         _initialize: function(x, y) {
  776.             this._x = x || 0;
  777.             this._y = y || 0;
  778.         },
  779.  
  780.         /**
  781.          * Gets called on every update cycle, for each particle. Accelerates the particle by the given values.
  782.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  783.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  784.          * @param {number} index - The given particle's position inside the given emitter's children array.
  785.          */
  786.         update: function(emitter, particle, index) {
  787.             particle.velocity.x += this._x;
  788.             particle.velocity.y += this._y;
  789.         }
  790.  
  791.     });
  792.  
  793.     //=============================================================================
  794.     // IAVRA.PARTICLE.BEHAVIOUR.PolarForce
  795.     //=============================================================================
  796.  
  797.     /**
  798.      * Applies a linear force to particles, that gets calculated from a polar vector.
  799.      */
  800.     $.PARTICLE.BEHAVIOUR.PolarForce.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  801.  
  802.         /**
  803.          * Initializes the behaviour.
  804.          * @param {number} [radius=0] - Radius component of the polar vector to apply.
  805.          * @param {number} [angle=0] - Angle component of the polar vector to apply, in degree.
  806.          */
  807.         _initialize: function(radius, angle) {
  808.             this._radius = radius || 0;
  809.             this._angle = _degToRad(angle || 0);
  810.         },
  811.  
  812.         /**
  813.          * Gets called on every update cycle, for each particle. Accelerates the particle by the given values.
  814.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  815.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  816.          * @param {number} index - The given particle's position inside the given emitter's children array.
  817.          */
  818.         update: function(emitter, particle, index) {
  819.             var vector = _polarVector(this._radius, this._angle);
  820.             particle.velocity.x += vector[0];
  821.             particle.velocity.y += vector[1];
  822.         }
  823.  
  824.     });
  825.  
  826.     //=============================================================================
  827.     // IAVRA.PARTICLE.BEHAVIOUR.RandomDrift
  828.     //=============================================================================
  829.  
  830.     /**
  831.      * Randomly accelerates particles.
  832.      */
  833.     $.PARTICLE.BEHAVIOUR.RandomDrift.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  834.  
  835.         /**
  836.          * Initializes the behaviour.
  837.          * @param {number} [x=0] - X component of the force vector to apply.
  838.          * @param {number} [y=0] - Y component of the force vector to apply.
  839.          */
  840.         _initialize: function(x, y) {
  841.             this._x = (x || 0) * 2;
  842.             this._y = (y || 0) * 2;
  843.         },
  844.  
  845.         /**
  846.          * Gets called on every update cycle, for each particle. Accelerates the particle by a random force in the
  847.          * range of ([-x;x[, [-y;y[).
  848.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  849.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  850.          * @param {number} index - The given particle's position inside the given emitter's children array.
  851.          */
  852.         update: function(emitter, particle, index) {
  853.             particle.velocity.x += (Math.random() - 0.5) * this._x;
  854.             particle.velocity.y += (Math.random() - 0.5) * this._y;
  855.         }
  856.  
  857.     });
  858.  
  859.     //=============================================================================
  860.     // IAVRA.PARTICLE.BEHAVIOUR.SpeedLimit
  861.     //=============================================================================
  862.  
  863.     /**
  864.      * Limits the velocity of particles to a given range.
  865.      */
  866.     $.PARTICLE.BEHAVIOUR.SpeedLimit.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  867.  
  868.         /**
  869.          * Initializes the behaviour.
  870.          * @param {number} [min=0] - Minimum velocity allowed for particles.
  871.          * @param {number} [max=0] - Maximum velocity allowed for particles.
  872.          */
  873.         _initialize: function(min, max) {
  874.             this._min = min || 0;
  875.             this._max = max || 0;
  876.             this._minSq = this._min * this._min;
  877.             this._maxSq = this._max * this._max;
  878.         },
  879.  
  880.         /**
  881.          * Gets called on every update cycle, for each particle. If the particle's velocity vector is lower or higher,
  882.          * than the given limits, it will be adjusted accordingly. Does not affect particles with 0 velocity.
  883.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  884.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  885.          * @param {number} index - The given particle's position inside the given emitter's children array.
  886.          */
  887.         update: function(emitter, particle, index) {
  888.             var speedSq = particle.velocity.x * particle.velocity.x + particle.velocity.y * particle.velocity.y;
  889.             if(speedSq < this._minSq) {
  890.                 var factor = this._min / Math.sqrt(speedSq);
  891.                 particle.velocity.x *= factor;
  892.                 particle.velocity.y *= factor;
  893.             } else if(speedSq > this._maxSq) {
  894.                 var factor = this._max / Math.sqrt(speedSq);
  895.                 particle.velocity.x *= factor;
  896.                 particle.velocity.y *= factor;
  897.             }
  898.         }
  899.  
  900.     });
  901.  
  902.     //=============================================================================
  903.     // IAVRA.PARTICLE.BEHAVIOUR.Attraction
  904.     //=============================================================================
  905.  
  906.     /**
  907.      * Places a gravity well at a given point, that will attract particles depending on their distance.
  908.      */
  909.     $.PARTICLE.BEHAVIOUR.Attraction.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  910.  
  911.         /**
  912.          * Initializes the behaviour.
  913.          * @param {PIXI.Point} center - Center point of the attraction.
  914.          * @param {number} force - Force to be applied to particles. This value will get scaled according to their
  915.          * distance from the center.
  916.          * @param {number} [epsilon=100] - Particles nearer than the given distance will be treated, as though they are
  917.          * that distance away. Prevents the gravity well from blowing up, when distances get low.
  918.          */
  919.         _initialize: function(center, force, epsilon) {
  920.             this._center = center;
  921.             this._force = force;
  922.             this._epsilon = _default(epsilon, 100);
  923.             this._epsilonSq = this._epsilon * this._epsilon;
  924.         },
  925.  
  926.         /**
  927.          * Gets called on every update cycle, for each particle. Attracts all particles to the center point, with an
  928.          * increasing force for shorter distances. A force too high or epsilon too low might cause particles to be
  929.          * catapulted away from the well.
  930.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  931.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  932.          * @param {number} index - The given particle's position inside the given emitter's children array.
  933.          */
  934.         update: function(emitter, particle, index) {
  935.             var x = this._center.x - particle.position.x;
  936.             var y = this._center.y - particle.position.y;
  937.             var distanceSq = x * x + y * y;
  938.             if(distanceSq === 0) { return; }
  939.             var distance = Math.sqrt(distanceSq);
  940.             if(distanceSq < this._epsilonSq) { distanceSq = this._epsilonSq; };
  941.             var factor = this._force * 10000 / (distanceSq * distance);
  942.             particle.velocity.x += x * factor;
  943.             particle.velocity.y += y * factor;
  944.         }
  945.  
  946.     });
  947.  
  948.     //=============================================================================
  949.     // IAVRA.PARTICLE.BEHAVIOUR.Repulsion
  950.     //=============================================================================
  951.  
  952.     /**
  953.      * Places an anti-gravity well at a given point, that will repel particles depending on their distance.
  954.      */
  955.     $.PARTICLE.BEHAVIOUR.Repulsion.prototype = _extend(Object.create($.PARTICLE.BEHAVIOUR.Attraction.prototype), {
  956.  
  957.         /**
  958.          * Initializes the behaviour.
  959.          * @param {PIXI.Point} center - Center point of the repulsion.
  960.          * @param {number} force - Force to be applied to particles. This value will get scaled according to their
  961.          * distance from the center.
  962.          * @param {number} [epsilon=100] - Particles nearer than the given distance will be treated, as though they are
  963.          * that distance away.
  964.          */
  965.         _initialize: function(center, force, epsilon) {
  966.             $.PARTICLE.BEHAVIOUR.Attraction.prototype._initialize.call(this, center, -force, epsilon)
  967.         },
  968.  
  969.     });
  970.  
  971.     //=============================================================================
  972.     // IAVRA.PARTICLE.BEHAVIOUR.RotateToDirection
  973.     //=============================================================================
  974.  
  975.     /**
  976.      * Rotates particles to always face in the direction, they are moving to.
  977.      */
  978.     $.PARTICLE.BEHAVIOUR.RotateToDirection.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  979.  
  980.         /**
  981.          * Gets called on every update cycle, for each particle.
  982.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  983.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  984.          * @param {number} index - The given particle's position inside the given emitter's children array.
  985.          */
  986.         update: function(emitter, particle, index) {
  987.             particle.rotation = Math.atan2(-particle.velocity.y, particle.velocity.x);
  988.         }
  989.  
  990.     });
  991.  
  992.     //=============================================================================
  993.     // IAVRA.PARTICLE.BEHAVIOUR.Collision
  994.     //=============================================================================
  995.  
  996.     /**
  997.      * Applies collision between all particles of the emitter, depending on their radius and scale.
  998.      */
  999.     $.PARTICLE.BEHAVIOUR.Collision.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  1000.  
  1001.         /**
  1002.          * Initializes the behaviour.
  1003.          * @param {number} [bounce=1] - Bounce coefficient to be applied. Values between 0 and 1 will cause particles
  1004.          * to lose velocity on collision, while values > 0 will cause them to gain velocity.
  1005.          */
  1006.         _initialize: function(bounce) {
  1007.             this._bounce = _default(bounce, 1);
  1008.         },
  1009.  
  1010.         /**
  1011.          * Gets called on every update cycle, for each particle. Particles will bounce from each other, depending on
  1012.          * their radius and scale, with smaller particles getting pushed farer, than bigger ones.
  1013.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  1014.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  1015.          * @param {number} index - The given particle's position inside the given emitter's children array.
  1016.          */
  1017.         update: function(emitter, particle, index) {
  1018.             var pool = emitter.children, other, dx, dy, distance, lengthSq, factor, n1, n2, relN, m1, m2, f1, f2;
  1019.             for(var i = index + 1, max = pool.length; i < max; ++i) {
  1020.                 other = pool[i];
  1021.                 m1 = particle.radius * particle.scale.x;
  1022.                 m2 = other.radius * other.scale.x;
  1023.                 distance = m1 + m2;
  1024.                 dx = other.position.x - particle.position.x;
  1025.                 if(dx > distance || dx < -distance) { continue; }
  1026.                 dy = other.position.y - particle.position.y;
  1027.                 if(dy > distance || dy < -distance) { continue; }
  1028.                 lengthSq = dx * dx + dy * dy;
  1029.                 if(lengthSq <= distance * distance && lengthSq > 0) {
  1030.                     factor = 1 / Math.sqrt(lengthSq);
  1031.                     dx *= factor;
  1032.                     dy *= factor;
  1033.                     n1 = dx * particle.velocity.x + dy * particle.velocity.y;
  1034.                     n2 = dx * other.velocity.x + dy * other.velocity.y;
  1035.                     relN = n1 - n2;
  1036.                     if(relN > 0) {
  1037.                         factor = ((1 + this._bounce) * relN) / distance;
  1038.                         f1 = factor * m2;
  1039.                         f2 = -factor * m1;
  1040.                         particle.velocity.x -= f1 * dx;
  1041.                         particle.velocity.y -= f1 * dy;
  1042.                         other.velocity.x -= f2 * dx;
  1043.                         other.velocity.y -= f2 * dy;
  1044.                     }
  1045.                 }
  1046.             }
  1047.         }
  1048.  
  1049.     });
  1050.  
  1051.     //=============================================================================
  1052.     // IAVRA.PARTICLE.BEHAVIOUR.BoundingBox
  1053.     //=============================================================================
  1054.  
  1055.     /**
  1056.      * Restricts particles to a bounding box, causing them to bounce back, if they try to leave it. Particles should
  1057.      * spawn inside the box, to prevent unpredictable side effects.
  1058.      */
  1059.     $.PARTICLE.BEHAVIOUR.BoundingBox.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  1060.  
  1061.         /**
  1062.          * Initializes the behaviour.
  1063.          * @param {number} x - X component of the box's upper left corner.
  1064.          * @param {number} y - Y component of the box's upper left corner.
  1065.          * @param {number} width - Width of the box.
  1066.          * @param {number} height - Height of the box.
  1067.          * @param {number} [bounce=1] - Bounce coefficient to be applied. Values between 0 and 1 will cause particles
  1068.          * to lose velocity on collision, while values > 0 will cause them to gain velocity.
  1069.          */
  1070.         _initialize: function(x, y, width, height, bounce) {
  1071.             this._left = x;
  1072.             this._top = y;
  1073.             this._right = x + width;
  1074.             this._bottom = y + height;
  1075.             this._bounce = _default(bounce, 1);
  1076.         },
  1077.  
  1078.         /**
  1079.          * Gets called on every update cycle, for each particle. Particles will bounce off the inside of the box, to
  1080.          * keep them inside.
  1081.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  1082.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  1083.          * @param {number} index - The given particle's position inside the given emitter's children array.
  1084.          */
  1085.         update: function(emitter, particle, index) {
  1086.             var radius = particle.radius * particle.scale.x, position;
  1087.             if(particle.velocity.x > 0 && (position = particle.position.x + radius) >= this._right) {
  1088.                 particle.velocity.x *= -this._bounce;
  1089.                 particle.position.x += 2 * (this._right - position);
  1090.             } else if(particle.velocity.x < 0 && (position = particle.position.x - radius) <= this._left) {
  1091.                 particle.velocity.x *= -this._bounce;
  1092.                 particle.position.x += 2 * (this._left - position);
  1093.             }
  1094.             if(particle.velocity.y > 0 && (position = particle.position.y + radius) >= this._bottom) {
  1095.                 particle.velocity.y *= -this._bounce;
  1096.                 particle.position.y += 2 * (this._bottom - position);
  1097.             } else if(particle.velocity.y < 0 && (position = particle.position.y - radius) <= this._top) {
  1098.                 particle.velocity.y *= -this._bounce;
  1099.                 particle.position.y += 2 * (this._top - position);
  1100.             }
  1101.         }
  1102.  
  1103.     });
  1104.  
  1105.     //=============================================================================
  1106.     // IAVRA.PARTICLE.BEHAVIOUR.WrapAroundBox
  1107.     //=============================================================================
  1108.  
  1109.     /**
  1110.      * Restricts particles to a bounding box, causing them to wrap around to the other side, if they try to leave it.
  1111.      * Particles should spawn inside the box, to prevent unpredictable side effects.
  1112.      */
  1113.     $.PARTICLE.BEHAVIOUR.WrapAroundBox.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  1114.  
  1115.         /**
  1116.          * Initializes the behaviour.
  1117.          * @param {number} x - X component of the box's upper left corner.
  1118.          * @param {number} y - Y component of the box's upper left corner.
  1119.          * @param {number} width - Width of the box.
  1120.          * @param {number} height - Height of the box.
  1121.          */
  1122.         _initialize: function(x, y, width, height) {
  1123.             this._left = x;
  1124.             this._top = y;
  1125.             this._right = x + width;
  1126.             this._bottom = y + height;
  1127.             this._width = width;
  1128.             this._height = height;
  1129.         },
  1130.  
  1131.         /**
  1132.          * Gets called on every update cycle, for each particle. Particles leaving the box will appear on the other
  1133.          * side, to keep them inside.
  1134.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  1135.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  1136.          * @param {number} index - The given particle's position inside the given emitter's children array.
  1137.          */
  1138.         update: function(emitter, particle, index) {
  1139.             if (particle.velocityx > 0 && particle.position.x >= this._right) {
  1140.                 particle.position.x -= this._width;
  1141.             } else if (particle.velocity.x < 0 && particle.position.x <= this._left) {
  1142.                 particle.position.x += this._width;
  1143.             }
  1144.             if(particle.velocity.y > 0 && particle.position.y >= this._bottom) {
  1145.                 particle.position.y -= this._height;
  1146.             } else if (particle.velocity.y < 0 && particle.position.y <= this._top) {
  1147.                 particle.position.y += this._height;
  1148.             }
  1149.         }
  1150.  
  1151.     });
  1152.  
  1153.     //=============================================================================
  1154.     // IAVRA.PARTICLE.BEHAVIOUR.CollisionZone
  1155.     //=============================================================================
  1156.  
  1157.     /**
  1158.      * Applies collision between particles and the given zone, both from the inside and outside.
  1159.      */
  1160.     $.PARTICLE.BEHAVIOUR.CollisionZone.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  1161.  
  1162.         /**
  1163.          * Initializes the behaviour.
  1164.          * @param {IAVAR.PARTICLE.Zone} zone - Zone used to apply collision.
  1165.          * @param {number} [bounce=1] - Bounce coefficient to be applied. Values between 0 and 1 will cause particles
  1166.          * to lose velocity on collision, while values > 0 will cause them to gain velocity.
  1167.          */
  1168.         _initialize: function(zone, bounce) {
  1169.             this._zone = zone;
  1170.             this._bounce = _default(bounce, 1);
  1171.         },
  1172.  
  1173.         /**
  1174.          * Gets called on every update cycle, for each particle. Causes particles to bounce off the given zone.
  1175.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  1176.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  1177.          * @param {number} index - The given particle's position inside the given emitter's children array.
  1178.          */
  1179.         update: function(emitter, particle, index) {
  1180.             this._zone.collide(particle, this._bounce);
  1181.         }
  1182.  
  1183.     });
  1184.  
  1185.     //=============================================================================
  1186.     // IAVRA.PARTICLE.BEHAVIOUR.DeathZone
  1187.     //=============================================================================
  1188.  
  1189.     /**
  1190.      * Destroys all particles in- or outside the given zone.
  1191.      */
  1192.     $.PARTICLE.BEHAVIOUR.DeathZone.prototype = _extend(Object.create($.PARTICLE.Behaviour.prototype), {
  1193.  
  1194.         /**
  1195.          * Initializes the behaviour.
  1196.          * @param {IAVAR.PARTICLE.Zone} zone - Zone to be used.
  1197.          * @param {boolean} [killOutside=false] - If set to true, will destroy all particles outside the zone, instead.
  1198.          */
  1199.         _initialize: function(zone, killOutside) {
  1200.             this._zone = zone;
  1201.             this._killOutside = !!killOutside;
  1202.         },
  1203.  
  1204.         /**
  1205.          * Gets called on every update cycle, for each particle. Destroys all particles in- or outside the given zone,
  1206.          * depending on the "killOutside" parameter.
  1207.          * @param {IAVRA.PARTICLE.Emitter} emitter - Emitter instance containing the given particle.
  1208.          * @param {IAVRA.PARTICLE.Particle} particle - Particle to be updated.
  1209.          * @param {number} index - The given particle's position inside the given emitter's children array.
  1210.          */
  1211.         update: function(emitter, particle, index) {
  1212.             if(this._zone.contains(particle.position.x, particle.position.y) !== this._killOutside) {
  1213.                 particle.dead = true;
  1214.             }
  1215.         }
  1216.  
  1217.     });
  1218.  
  1219. })(this.IAVRA || (this.IAVRA = {}));
Add Comment
Please, Sign In to add comment