ActionScript 3.0 Particle Systems #4: Bubbles
r3dux | January 13, 2010Yet more ActionScript 3.0 again! This time it’s a kind of 2D particle fountain. New in this iteration is code so we can pause and resume the animation instead of just start/stopping it, and each bubble’s colour gets subtley modified via colorTransforms.
Last one for the day methinks – I’m knackered. Happy, but knackered
As usual, source code and flash files after the jump for those of a particularly masochistic bent…
Flash File (ActionScript 3.0) Code:
import flash.events.KeyboardEvent; import Bubble; // Function to return us a random number which is within a specified range function randRange(low:Number, high:Number):Number { var randNum:Number = (Math.random() * (high - low)) + low; return randNum; } // Define our vector (just a dynamic array with a specied type in AS3!) var bubbleVect:Vector.<Bubble> = new Vector.<Bubble>; // Define our number of bubbles to display on the screen and a start/stop animation flag var numberOfBubbles:uint = 60; var toggleAnimation:Boolean = false; var bubblesExist:Boolean = false; // Create our controls message, center it and add it to the screen var msg:ControlsMessage = new ControlsMessage(); msg.x = stage.stageWidth / 2; msg.y = 50; addChild(msg); // Create a flag to only show our controls message once var showMsg:Boolean = true; function addBubbles():void { // Create variables to store our x & y speeds, which get passed to the Bubble constructor var bubbleXSpeed:Number; var bubbleYSpeed:Number; // Create however many Bubbles we've entered into our numberOfBubbles variable for (var loop:uint = 0; loop < numberOfBubbles; loop++) { // If there are no bubbles on the stage, then create a new instance of Bubble, // sets it's properties and add it to our Vector of Bubbles if (bubblesExist == false) { bubbleVect.push(new Bubble(bubbleXSpeed, bubbleYSpeed)); // Set the initial x (horizontal) and y (vertical) location on stage bubbleVect[loop].x = 250; bubbleVect[loop].y = 245; // Randomise alpha bubbleVect[loop].alpha = Math.random(); // Randomise our bubble size to between 30% and 40% of the symbol's original size var sizeScale:Number = Math.random() * 0.4; if (sizeScale < 0.3) { sizeScale = 0.3; } bubbleVect[loop].scaleX = sizeScale; bubbleVect[loop].scaleY = sizeScale; // Randomise our Bubble colour bubbleVect[loop].randomiseBubbleColour(); // Add the Bubble to the stage addChild(bubbleVect[loop]); } else { // Otherwise re-instate the event listener on each bubble leaving // existing properties alone (so we continue where we left off) bubbleVect[loop].rebindBubble(); } // End of if bubblesExist condition } // End of for loop // Set our flag to say the bubbles now exist bubblesExist = true; } // End of addBubbles function function removeBubbles():void { // Loop through our vector of bubbles and... for (var loop:uint = 0; loop < numberOfBubbles; loop++) { // ...call our custom destructor to unbind any Bubble eventListeners bubbleVect[loop].BubbleDestructor(); } } // End of removeBubbles function function bubbleController(e:KeyboardEvent):void { // If the animation is stopped and a key is pressed, add the Bubbles and flip the flag if (toggleAnimation == false) { addBubbles(); toggleAnimation = true; // Only remove message after first display, as it'll only be on stage once if (showMsg == true) { showMsg = false; removeChild(msg); } } else { // Otherwise animation must be running and we want it to stop, so remove the // bubbles and flip the flag removeBubbles(); toggleAnimation = false; } } // End of bubbleController function // With all our functions in place, bind the Bubble controller function to a keypress stage.addEventListener(KeyboardEvent.KEY_DOWN, bubbleController); |
ActionScript 3.0 Bubble Class Code:
package { // Import the classes we're going to use import flash.display.MovieClip; import flash.events.Event; import flash.geom.ColorTransform; public class Bubble extends MovieClip { // Define our class properties var xSpeed:Number; var ySpeed:Number; var alphaDecay:Number; var fadeBack:Boolean; // Define our class static variables static var gravity:Number = 0.1; static var maxXSpeed:Number = 4; static var maxYSpeed:Number = -5; // Class Constructor public function Bubble(theXSpeed:Number, theYSpeed:Number):void { // Add an event listener to each instance of a bubble so that it's updated every // time there's a new frame (default: 24 times a second, i.e. 24fps) this.addEventListener(Event.ENTER_FRAME, updateBubble); // Randomise the x and y speed of the Bubble between a given range // and set a random alpha (transparency) decay speed this.xSpeed = (Math.random() * maxXSpeed) - (maxXSpeed / 3.5); this.ySpeed = (Math.random() * maxYSpeed) + (maxYSpeed / 2); this.alphaDecay = Math.random() / 50; // Initially, we don't want our our Bubbles to quickly fade in this.fadeBack = false; } // Destructor to unbind the bubble's ENTER_FRAME event listener when we destroy it public function BubbleDestructor():void { this.removeEventListener(Event.ENTER_FRAME, updateBubble); } public function rebindBubble():void { this.addEventListener(Event.ENTER_FRAME, updateBubble); } public function randomiseBubbleColour():void { var myColourTransform:ColorTransform = this.transform.colorTransform; // This will change the color of all layers and all sub-symbols within this symbol: //myColourTransform.color = 0xff0000; // Shift each colour channel (you can shift in the range: -255 to 255). myColourTransform.redOffset = (Math.random() * 200) - 100; // Range: -255 to +255 myColourTransform.greenOffset = (Math.random() * 200) - 100; // Range: -255 to +255 myColourTransform.blueOffset = (Math.random() * 200) - 100; // Range: -255 to +255 // This number will multiply by the green channel only (decimal value). There is also a redMultiplier and blueMultiplier. // This will essentially saturate/desaturate the color channel. // colorTransform.greenMultiplier = 2; // re-assign the ColorTransform back to this symbol this.transform.colorTransform = myColourTransform; } // Function to update a bubble, bound to Event.ENTER_FRAME, so called once per frame public function updateBubble(e:Event):void { // Add a small amount to our y speed to simulate gravity this.ySpeed += gravity; // Add our randomised x and y speeds to our Bubble position this.x += xSpeed; this.y += ySpeed; // Subtract a small amount from our object's alpha so it fades out this.alpha -= this.alphaDecay; // Reset bubble properties when it's faded out so much it's completely transparent if (this.alpha <= 0) { // Reset the initial x and set the y location of our bubbles this.x = 250; this.y = 245; // Re-randomise our x and y speeds within a given range this.xSpeed = (Math.random() * maxXSpeed) - (maxXSpeed / 3.5); this.ySpeed = (Math.random() * maxYSpeed) + (maxYSpeed / 2); // Re-randomise our Bubble colour this.randomiseBubbleColour(); // Set out fadeBack flag to true this.fadeBack = true; } // When a bubble has completely faded out fade it back in quickly if (this.fadeBack == true) { this.alpha += 0.10; // When we're fully opaque again stop making any further fadeBack alpha changes if (this.alpha >= 1) { this.fadeBack = false; } } } // End of updateBubble function } // End of Bubble class } // End of package |
In accordance with the prophesy, Adobe Flash CS4 files for the above can be found: here.










