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 );
}
}
}
Très sympa, beau boulot Francis !
Posted by Virginie | 4 janvier 2009, 21 h 22 min