The effect is as follows:
Click here to download the source file
Main code:
Import flash.display.*;
Import flash.filters.*;
Import flash.geom.*;
Import De.popforge.bitmap.Shape;
Shape.setcontainer (this.createemptymovieclip (' shapes ', 10000));
--Get blue circle as a bitmap
var bluespotclip:movieclip = Attachmovie ("Bluespot", "Bluespotclip", 0);
var clipbounds:object = Bluespotclip.getbounds ();
var bluespot:bitmapdata = new BitmapData (Clipbounds.xmax, Clipbounds.ymax, True, 0);
Bluespot.draw (Bluespotclip, New Matrix ());
Bluespotclip.removemovieclip ();
--involved bitmaps
var source:bitmapdata = new BitmapData (256, 256, FALSE, 0);
var output:bitmapdata = new BitmapData (256, 256, FALSE, 0);
var buffer:bitmapdata = new BitmapData (256, 256, FALSE, 0);
var bounds:rectangle = new Rectangle (0, 0, 256, 256);
var origin:point = new Point ();
var Matrix:matrix = new Matrix ();
--Creating a gradient with fire colors
Import de.popforge.bitmap.Gradient;
var Firepalette:array = Gradient.fillarray
(
[0, 0xa20000, 0xfff122, 0xFFFFFF, 0XF8FF1B, 0XC53C05, 0],
[0, 50, 50, 100, 75, 25, 0],
[0, 64, 132, 186, 220, 250, 255]
);
--Filter to let the flame grow
var flame:convolutionfilter = new Convolutionfilter (3, 3, NULL, 2.7,-2);
Attachbitmap (output, 0, False, false);
var ms:number = Gettimer ();
var frame:number = 0;
OnMouseMove = function ()
{
--Create burning area
var mouse:point = new Point (_XMOUSE-CLIPBOUNDS.XMAX/2, _YMOUSE-CLIPBOUNDS.YMAX/2);
Source.copypixels (Bluespot, New Rectangle (0, 0, Clipbounds.xmax, Clipbounds.ymax), mouse);
}
Onenterframe = function ()
{
--Create burning area
var mouse:point = new Point (_XMOUSE-CLIPBOUNDS.XMAX/2, _YMOUSE-CLIPBOUNDS.YMAX/2);
Source.copypixels (Bluespot, New Rectangle (0, 0, Clipbounds.xmax, Clipbounds.ymax), mouse);
--the Flames matrix with some randoms to expand the flame sidewards
var flamematrix:array = [0, 0, 0, 0, 0.2, 0, 0, 1.6, 0];
FLAMEMATRIX[3] = Math.random () *. 001;
FLAMEMATRIX[5] = Math.random () *. 001;
FLAMEMATRIX[6] =. 4 + math.random () *. 1;
FLAMEMATRIX[8] =. 4 + math.random () *. 1;
Flame.matrix = Flamematrix;
--Applying the filter 3 times to increase the flame speed
--compute the affected region by "Generatefilterrect", "Getcolorboundsrect"
var area:rectangle = Source.generatefilterrect (Source.getcolorboundsrect (0xFF, 0, false), flame);
Source.applyfilter (source, area, area.topleft, flame);
Area = Source.generatefilterrect (area, flame);
Source.applyfilter (source, area, area.topleft, flame);
Area = Source.generatefilterrect (area, flame);
Source.applyfilter (source, area, area.topleft, flame);
--Remap the flame bitmap with fire colors
Output.palettemap (source, area, area.topleft, NULL, NULL, Firepalette);
--fps
if (Gettimer ()-1000 > ms)
{
ms = Gettimer ();
fps = frame;
Fpsdisplay.text = Fps.tostring ();
frame = 0;
}
Else
{
frame++;
}
}
var Mousedown:boolean = false;
OnMouseDown = function ()
{
MouseDown = true;
}
OnMouseUp = function ()
{
Onenterframe ();
MouseDown = false;
}
Createtextfield ("Fpsdisplay", 99, 0, 0, 60, 20);
Fpsdisplay.textcolor = 0XFFFFFF;
Fpsdisplay.selectable = false;
Corresponding as code: gradient.as
Import De.popforge.bitmap.Shape;
Import Flash.display.BitmapData;
Import Flash.geom.ColorTransform;
Import Flash.geom.Matrix;
Class De.popforge.bitmap.Gradient
{
public static function Createxygradient (): BitmapData
{
/*
* Get Canvas
*/
var g:shape = Shape.get ();
if (g = = null)
{
return null;
}
var xygradient:bitmapdata = new BitmapData (256, 256, FALSE, 0);
var Matrix:matrix = new Matrix ();
/*
* Create y as blue colorvalues
*/
Matrix.creategradientbox (256, 256, MATH.PI/2, 0, 0);
G.begingradientfill (' linear ', [0, 0x0000ff], [MB], [0, 0xFF], matrix);
G.moveto (0, 0);
G.lineto (256, 0);
G.lineto (256, 256);
G.lineto (0, 256);
G.lineto (0, 0);
G.endfill ();
Matrix.identity ();
Xygradient.draw (g, Matrix);
G.clear ();
/*
* Create X as Green Colorvalues
*/
Matrix.creategradientbox (256, 256, 0, 0, 0);
G.begingradientfill (' linear ', [0, 0x00ff00], [MB], [0, 0xFF], matrix);
G.moveto (0, 0);
G.lineto (256, 0);
G.lineto (256, 256);
G.lineto (0, 256);
G.lineto (0, 0);
G.endfill ();
Matrix.identity ();
Xygradient.draw (g, Matrix, NULL, ' Add ');
G.removemovieclip ();
return xygradient;
}
public static function Createdisplacementmapfrommidmap (midmap:bitmapdata): BitmapData
{
var displace:bitmapdata = createxygradient ();
if (displace = null)
{
return null;
}
var colortransform:colortransform = new ColorTransform ();
var M:matrix = new Matrix ();
Colortransform.greenmultiplier =. 5;
Colortransform.bluemultiplier =. 5;
Displace.draw (Displace, M, colortransform);
Colortransform.greenoffset = 128;
Colortransform.blueoffset = 128;
Displace.draw (Midmap, M, ColorTransform, ' difference ');
return displace;
}
/*
* Returns an array with 32bit colorvalues
* Usefull to remap a bitmap using ' Palettemap '
*/
public static function Fillarray (Colors:array, Alphas:array, Ratios:array): Array
{
var g:shape = Shape.get ();
if (g = = null)
{
return null;
}
var array:array = new Array;
var M:matrix = new Matrix ();
M.A = M.D =. 15625;
M.B = M.C = 0;
M.TX = M.ty = 128;
G.begingradientfill (' linear ', colors, alphas, ratios, m);
G.moveto (0, 0);
G.lineto (256, 0);
G.lineto (256, 1);
G.lineto (0, 1);
G.lineto (0, 0);
G.endfill ();
var bmp:bitmapdata = new BitmapData (256, 1, true, 0);
M.identity ();
Bmp.draw (g, M);
G.removemovieclip ();
var x:number = 256;
while (--x >-1)
{
ARRAY[X] = bmp.getpixel32 (x, 0);
}
return array;
}
}
Shap.as
Import Flash.display.BitmapData;
Class De.popforge.bitmap.Shape extends MovieClip
{
static var id:string = ' __packages.de.popforge.bitmap.shape ';
Static private Var Container:movieclip;
static public Function Setcontainer (container:movieclip): Void
{
Shape.container = container;
Object.registerclass (ID, Shape);
}
static public Function Get (): Shape
{
if (container = = undefined)
{
Trace (' Error:no container is defined. Call Shape.setcontainer (Timeline:movieclip);
return null;
}
var d:number = container.getnexthighestdepth ();
Return Shape (Container.attachmovie (ID, d.tostring (), d));
}
Public Function Rasterize (target:bitmapdata): Void
{
Target.draw (this);
}
}