// you’re reading...

tech

old school fire effect

After my last plasma experiments, I feel motivated to play again with pixels and old school demoscene effects. I continued to explore the same great C++ CG resource
So, here’s another one effect that I’m glad to share. This is the old shool fire effect.

No tricks deployed this time to optimize Flash rendering. That’s a standard implementation.

[kml_flashembed movie="http://www.tweenpix.net/files/fire.swf" width="450" height="175"/]

Here’s the source code. Enjoy !

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	[SWF( width="450", height="175", frameRate="25" , backgroundColor="0x000000")]
	public class Fire
		extends Sprite
	{
		protected const w : int = 450;
		protected const h : int = 175;

		protected var bd : BitmapData;
		protected var p : Point;
		protected var rect : Rectangle;
		protected var blur : BlurFilter;

		protected var palette : Vector.;
		protected var fire : Array;

		public function Fire()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.LOW;

			p = new Point(0, 0);
			rect = new Rectangle( 0, 0, w, h );
			blur = new BlurFilter( 4, 4, 1 );
			bd = new BitmapData( w, h, false, 0xFFFFFF );
			addChild( new Bitmap( bd ) );

			var x : int, y : int;
			palette = new Vector.( 256, false );
			fire = [];
			for ( x = 0; x < w; x++ ) fire[x] = new Vector.( h, false );
		    for ( x = 0; x < w; x++ )
		    	for ( y = 0; y < h; y++ )
					fire[x][y] = 256;
			for ( x = 0; x < 256; x++ )
				palette[x++] = HSLtoRGB( x/(3 * 256), 1, Math.min( 256, x * 2 )/256 );

			addEventListener( Event.ENTER_FRAME, enterFrame );
		}

		protected function enterFrame( e : Event ) : void
		{
			bd.lock();
			var x : int, y : int;
		    for ( x = 0; x < w; x++ ) fire[x][h - 1] = Math.random()*32768 % 256;
		    for ( y = 0; y < h - 1; y++ )
    			for ( x = 0; x < w; x++ )
			      fire[x][y] = ((fire[(x - 1 + w) % w][(y + 1) % h]
					+ fire[(x) % w][(y + 1) % h]
			        + fire[(x + 1) % w][(y + 1) % h]
			        + fire[(x) % w][(y + 2) % h]) * 32) / 129;
		    for ( x = 0; x < w; x++ )
			    for ( y = 0; y < h-1; y++ )
			    	bd.setPixel( x, y, palette[fire[x][y]]);
			bd.applyFilter( bd, bd.rect, p, blur );
			bd.unlock();
		}

		public static function HSLtoRGB( h :Number, s : Number , l : Number ) : Number
		{
		    var r : Number = 0, g : Number = 0, b : Number = 0, v1 : Number, v2 : Number;
		    if ( s == 0 )
		    {
		       r = l * 255;
		       g = l * 255;
		       b = l * 255;

		    } else
		    {
		       v2 = ( l < .5 ) ? l * ( 1 + s ) : ( l + s ) - ( s * l );
		       v1 = 2 * l - v2;
		       r = 255 * HueToRGB( v1, v2, h + ( 1 / 3 ) );
		       g = 255 * HueToRGB( v1, v2, h );
		       b = 255 * HueToRGB( v1, v2, h - ( 1 / 3 ) );
		    }
		    return ((r << 16)|(g << 8)|b);
		}

		private static function HueToRGB( v1 : Number, v2 : Number, vH : Number ) : Number
	    {
		    if ( vH < 0 ) vH += 1;
		    if ( vH > 1 ) vH -= 1;
		    if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );
		    if ( ( 2 * vH ) < 1 ) return ( v2 );
		    if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );
	    	return ( v1 );
		}
	}
}

Discussion

One Response to “old school fire effect”

  1. Très sympa, beau boulot Francis !

    Posted by Virginie | 4 janvier 2009, 21 h 22 min

Post a comment