Personal tools
shadowfax.org.uk logo
Views

Particle Explosion

From Shadowfax

Jump to: navigation, search

Particle Explosion in ActionScript 3.0

This is my attempt at an oil explosion in ActionScript 3.0. It's gone through a number of iterations to get to this stage, and I'm still not 100% happy with it - but it is starting to look a bit like I imagined it.

Current version is not the most memory efficient - would be better to have one instance of the test bitmap rather than one per particle.

The Main Loop

package 
{
  import flash.display.Sprite;
  import flash.events.Event;
 
  public class Main extends Sprite
  {
    private var pArr:Array = new Array();
 
    public function Main():void
    {
      explode(Math.random() * 300 + 100,Math.random() * 150 + 100);
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }
 
    private function explode(px:int,py:int):void
    {
    for (var i:int = 0; i < 200; i++) 
      {
        pArr[i] = new particle(px,py);
        addChild(pArr[i]);
      }
    }
 
    private function onEnterFrame(e:Event):void 
    {
      // Animation loop
      for (var i:int = 0; i < pArr.length; i++) 
      {
        if (!pArr[i].animate())
        {
          // Remove empty particles
          pArr[i].bitmapData.dispose();
          removeChild(pArr[i]);
          pArr.splice(i--, 1);
        }
      }
      // If all gone explode again!
      if (pArr.length == 0) explode(Math.random() * 300 + 100,Math.random() * 150 + 100);
    }
  }
}

The Particle Object

package  
{
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.Shape;
  import flash.filters.BlurFilter;
  import flash.geom.Point;
  import flash.geom.Rectangle;
 
  public class particle extends Bitmap 
  {
    private var bmdTest:BitmapData;
    private var srad:Number = Math.random() * 20 + 5;
    private var course:Number = Math.random() * 360;
    private var iColor:Number;
    private var sRect:Rectangle;
    private var sPt:Point = new Point();
    private var iBF:BlurFilter = new BlurFilter(9, 9, 1);
 
    private var xSp:Number;
    private var ySp:Number;
 
    private var colArr:Array = new Array(0xff0000, 0xff4400, 0xff8800, 0xffcc00, 0xffff00,
           0xffff00, 0x444444, 0x333333, 0x333333, 0x222222, 0x222222, 0x111111, 0x111111,
           0x111111, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000);
 
    public function particle(aX:int, aY:int) 
    {
      // Set up bitmap large enough for particle to blur into
      sRect = new Rectangle(0, 0, srad * 6, srad * 6);
      bitmapData = new BitmapData(srad * 6, srad * 6, true, 0x000000);
      bmdTest = new BitmapData(srad * 6, srad * 6, true, 0x000000);
 
      // Choose a colour
      iColor = colArr[Math.floor(Math.random() * 20)];
 
      // Draw the starting particle
      var sh:Shape = new Shape();
      sh.graphics.beginFill(iColor);
      sh.graphics.drawCircle(srad * 1.5, srad * 1.5, srad * .5);
      sh.graphics.endFill();
      bitmapData.draw(sh);
 
      // Apply an initial blur
      bitmapData.applyFilter(bitmapData, sRect, sPt, iBF);
 
      // Position the particle
      x = aX - srad * 1.5;
      y = aY - srad * 1.5;
 
      // set the start velocity and direction
      xSp = Math.random()*Math.cos(course)*10;
      ySp = Math.random()*Math.sin(course)*10;
    }
 
    public function animate():Boolean 
    {
      var ret:Boolean = true;
 
      // Move the particle
      x += xSp;
      y += ySp;
 
      // Decelerate the particle movement
      xSp = xSp * .84;
      ySp = ySp * .84;
 
      // Randomly blur some of the particles each frame
      // Keeps the fireball from fading too quickly
      if (Math.random() < .5)
      {
        // increase the blur
        bitmapData.applyFilter(bitmapData, sRect, sPt, iBF);
 
        // Test if blurred to nothing. return false if so
        if (!bitmapData.compare(bmdTest)) ret = false;
      }
      return ret;
    }
  }
}


Leave your comment

Menu