Brownian Motion

This example simulates Brownian Motion. It demonstrates Flint’s built-in collision handling between particles.

The example also includes a custom action created to show and hide the air particles.

package
{
  import org.flintparticles.twoD.emitters.Emitter2D;
  import org.flintparticles.twoD.renderers.DisplayObjectRenderer;

  import flash.display.Sprite;

  [SWF(width='500', height='500', frameRate='60', backgroundColor='#000000')]
  
  public class Main extends Sprite
  {
    private var emitter:Emitter2D;
    
    public function Main()
    {
      emitter = new BrownianMotion( stage );

      var renderer:DisplayObjectRenderer = new DisplayObjectRenderer();
      renderer.addEmitter( emitter );
      addChild( renderer );

      emitter.start();
    }
  }
}
package
{
  import org.flintparticles.common.counters.Blast;
  import org.flintparticles.common.displayObjects.Dot;
  import org.flintparticles.common.initializers.ChooseInitializer;
  import org.flintparticles.common.initializers.CollisionRadiusInit;
  import org.flintparticles.common.initializers.ColorInit;
  import org.flintparticles.common.initializers.ImageClass;
  import org.flintparticles.common.initializers.InitializerGroup;
  import org.flintparticles.common.initializers.MassInit;
  import org.flintparticles.twoD.actions.BoundingBox;
  import org.flintparticles.twoD.actions.Collide;
  import org.flintparticles.twoD.actions.Move;
  import org.flintparticles.twoD.emitters.Emitter2D;
  import org.flintparticles.twoD.initializers.Position;
  import org.flintparticles.twoD.initializers.Velocity;
  import org.flintparticles.twoD.zones.DiscZone;
  import org.flintparticles.twoD.zones.RectangleZone;

  import flash.display.DisplayObject;
  import flash.geom.Point;

  public class BrownianMotion extends Emitter2D
  {
    public function BrownianMotion( stage:DisplayObject )
    {
      counter = new Blast( 500 );
      
      var air:InitializerGroup = new InitializerGroup();
      air.addInitializer( new ImageClass( Dot, [2] ) );
      air.addInitializer( new ColorInit( 0xFF666666, 0xFF666666 ) );
      air.addInitializer( new MassInit( 1 ) );
      air.addInitializer( new CollisionRadiusInit( 2 ) );
      
      var smoke:InitializerGroup = new InitializerGroup();
      smoke.addInitializer( new ImageClass( Dot, [10] ) );
      smoke.addInitializer( new ColorInit( 0xFFFFFFFF, 0xFFFFFFFF ) );
      smoke.addInitializer( new MassInit( 10 ) );
      smoke.addInitializer( new CollisionRadiusInit( 10 ) );
      
      addInitializer( new Position( new RectangleZone( 0, 0, 500, 500 ) ) );
      addInitializer( new Velocity( new DiscZone( new Point( 0, 0 ), 150, 100 ) ) );
      addInitializer( new ChooseInitializer( [ air, smoke ], [ 30, 1 ] ) );
      
      addAction( new Move() );
      addAction( new Collide( 1 ) );
      addAction( new BoundingBox( 0, 0, 500, 500, 1 ) );
      addAction( new ShowAirAction( stage ) );
    }
  }
}
package
{
  import flash.display.DisplayObject;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;
  
  import org.flintparticles.common.actions.ActionBase;
  import org.flintparticles.common.emitters.Emitter;
  import org.flintparticles.common.particles.Particle;  

  

  public class ShowAirAction extends ActionBase
  {
    private var _isDown:Boolean;
    
    
    public function ShowAirAction( stage:DisplayObject )
    {
      _isDown = false;
      stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownListener, false, 0, true );
      stage.addEventListener( KeyboardEvent.KEY_UP, keyUpListener, false, 0, true );
    }
    
    private function keyDownListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = true;
      }
    }
    private function keyUpListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = false;
      }
    }

    
    override public function update( emitter:Emitter, particle:Particle, time:Number ):void
    {
      if( particle.mass == 1 )
      {
        if( _isDown )
        {
          particle.color = 0;
        }
        else
        {
          particle.color = 0xFF666666;
        }
      }
    }
  }
}
import org.flintparticles.common.counters.Blast;
import org.flintparticles.common.debug.Stats;
import org.flintparticles.common.displayObjects.Dot;
import org.flintparticles.common.initializers.ChooseInitializer;
import org.flintparticles.common.initializers.CollisionRadiusInit;
import org.flintparticles.common.initializers.ColorInit;
import org.flintparticles.common.initializers.ImageClass;
import org.flintparticles.common.initializers.InitializerGroup;
import org.flintparticles.common.initializers.MassInit;
import org.flintparticles.twoD.actions.BoundingBox;
import org.flintparticles.twoD.actions.Collide;
import org.flintparticles.twoD.actions.Move;
import org.flintparticles.twoD.emitters.Emitter2D;
import org.flintparticles.twoD.initializers.Position;
import org.flintparticles.twoD.initializers.Velocity;
import org.flintparticles.twoD.renderers.DisplayObjectRenderer;
import org.flintparticles.twoD.zones.DiscZone;
import org.flintparticles.twoD.zones.RectangleZone;

var emitter:Emitter2D = new Emitter2D();
emitter.counter = new Blast( 500 );

var air:InitializerGroup = new InitializerGroup();
air.addInitializer( new ImageClass( Dot, [2] ) );
air.addInitializer( new ColorInit( 0xFF666666, 0xFF666666 ) );
air.addInitializer( new MassInit( 1 ) );
air.addInitializer( new CollisionRadiusInit( 2 ) );

var smoke:InitializerGroup = new InitializerGroup();
smoke.addInitializer( new ImageClass( Dot, [10] ) );
smoke.addInitializer( new ColorInit( 0xFFFFFFFF, 0xFFFFFFFF ) );
smoke.addInitializer( new MassInit( 10 ) );
smoke.addInitializer( new CollisionRadiusInit( 10 ) );

emitter.addInitializer( new Position( new RectangleZone( 0, 0, 500, 500 ) ) );
emitter.addInitializer( new Velocity( new DiscZone( new Point( 0, 0 ), 150, 100 ) ) );
emitter.addInitializer( new ChooseInitializer( [ air, smoke ], [ 30, 1 ] ) );

emitter.addAction( new Move() );
emitter.addAction( new Collide( 1 ) );
emitter.addAction( new BoundingBox( 0, 0, 500, 500, 1 ) );
emitter.addAction( new ShowAirAction( stage ) );

var renderer:DisplayObjectRenderer = new DisplayObjectRenderer();
renderer.addEmitter( emitter );
addChild( renderer );

emitter.start();
package
{
  import flash.display.DisplayObject;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;

  import org.flintparticles.common.actions.ActionBase;
  import org.flintparticles.common.emitters.Emitter;
  import org.flintparticles.common.particles.Particle;

  public class ShowAirAction extends ActionBase
  {
    private var _isDown:Boolean;
    
    public function ShowAirAction( stage:DisplayObject )
    {
      _isDown = false;
      stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownListener, false, 0, true );
      stage.addEventListener( KeyboardEvent.KEY_UP, keyUpListener, false, 0, true );
    }
    
    private function keyDownListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = true;
      }
    }
    private function keyUpListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = false;
      }
    }
    
    override public function update( emitter:Emitter, particle:Particle, time:Number ):void
    {
      if( particle.mass == 1 )
      {
        if( _isDown )
        {
          particle.color = 0;
        }
        else
        {
          particle.color = 0xFF666666;
        }
      }
    }
  }
}
<?xml version="1.0" encoding="utf-8"?>
<s:Application
  xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  xmlns:f="http://flintparticles.org/2009/flint2d"
  xmlns:local="*"
  width="500" height="500"
  backgroundColor="#000000">
  
<fx:Script>
  <![CDATA[
    import org.flintparticles.common.displayObjects.Dot;
  ]]>
</fx:Script>

<f:DisplayObjectRenderer id="renderer" width="500" height="500">
  <f:emitters>
    <f:Emitter id="emitter" autoStart="true">
      <f:counter>
        <f:Blast startCount="500"/>
      </f:counter>
      <f:initializers>
        <f:Position>
          <f:RectangleZone left="0" right="500" top="0" bottom="500"/>
        </f:Position>
        <f:Velocity>
          <f:DiscZone centerX="0" centerY="0" innerRadius="100" outerRadius="150"/>
        </f:Velocity>
        <f:ChooseInitializer weights="1,19">
          <f:InitializerGroup>
            <f:ImageClass imageClass="{Dot}" parameters="10"/>
            <f:CollisionRadiusInit radius="10"/>
            <f:MassInit mass="10"/>
            <f:ColorInit minColor="0xFFFFFFFF" maxColor="0xFFFFFFFF"/>
          </f:InitializerGroup>
          <f:InitializerGroup>
            <f:ImageClass imageClass="{Dot}" parameters="2"/>
            <f:CollisionRadiusInit radius="2"/>
            <f:MassInit mass="1"/>
            <f:ColorInit minColor="0xFF666666" maxColor="0xFF666666"/>
          </f:InitializerGroup>            
        </f:ChooseInitializer>
      </f:initializers>
      <f:actions>
        <f:Move/>
        <f:Collide bounce="1"/>
        <f:BoundingBox top="0" left="0" bottom="500" right="500" bounce="1"/>
        <local:ShowAirAction/>
      </f:actions>
    </f:Emitter>
  </f:emitters>
</f:DisplayObjectRenderer>
</s:Application>
package
{
  import org.flintparticles.common.actions.ActionBase;
  import org.flintparticles.common.emitters.Emitter;
  import org.flintparticles.common.particles.Particle;

  import mx.core.IMXMLObject;

  import flash.display.DisplayObject;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;

  public class ShowAirAction extends ActionBase implements IMXMLObject
  {
    private var _isDown:Boolean;
    
    public function ShowAirAction()
    {
      _isDown = false;
    }
    
    public function initialized( document:Object, id:String ):void
    {
      if( DisplayObject( document ).stage )
      {
        setStage( DisplayObject( document ).stage );
      }
      else
      {
        DisplayObject( document ).addEventListener( Event.ADDED_TO_STAGE, addedToStage );
      }
    }
      
    private function addedToStage( ev:Event ):void
    {
      setStage( ev.target.stage );
    }  
    
    private function setStage( stage:DisplayObject ):void
    {
      stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownListener, false, 0, true );
      stage.addEventListener( KeyboardEvent.KEY_UP, keyUpListener, false, 0, true );
    }
    
    private function keyDownListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = true;
      }
    }
    private function keyUpListener( ev:KeyboardEvent ):void
    {
      if( ev.keyCode == Keyboard.SHIFT )
      {
        _isDown = false;
      }
    }
    
    override public function update( emitter:Emitter, particle:Particle, time:Number ):void
    {
      if( particle.mass == 1 )
      {
        if( _isDown )
        {
          particle.color = 0;
        }
        else
        {
          particle.color = 0xFF666666;
        }
      }
    }
  }
}