package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.geom.Point; [SWF(width="465", height="465", frameRate="24")] public class Burn extends Sprite { private static const W:int = 64; private static const H:int = 64; private var palette:Array = [0x000000,0x010000,0x020000,0x030000,0x040000,0x050000,0x060000,0x070000,0x080000,0x090000,0x0a0000,0x0b0000,0x0c0000,0x0d0000,0x0e0000,0x0f0000,0x100000,0x110000,0x120000,0x130000,0x140000,0x150000,0x160000,0x170000,0x180000,0x190000,0x1a0000,0x1b0000,0x1c0000,0x1d0000,0x1e0000,0x1f0000,0x200000,0x220000,0x240000,0x260000,0x290000,0x2b0000,0x2d0000,0x300000,0x320000,0x340000,0x370000,0x390000,0x3b0000,0x3e0000,0x400000,0x420000,0x450000,0x470000,0x490000,0x4c0000,0x4e0000,0x500000,0x530000,0x550000,0x570000,0x5a0000,0x5c0000,0x5e0000,0x610000,0x630000,0x650000,0x680000,0x6a0000,0x6c0000,0x6e0000,0x710000,0x730000,0x750000,0x780000,0x7a0000,0x7c0000,0x7f0000,0x810000,0x830000,0x860000,0x880000,0x8a0000,0x8d0000,0x8f0000,0x910000,0x940000,0x960000,0x980000,0x9b0000,0x9d0000,0x9f0000,0xa20000,0xa40000,0xa60000,0xa90000,0xab0000,0xad0000,0xb00000,0xb20000,0xb40000,0xb60000,0xb90000,0xbb0000,0xbd0000,0xc00000,0xc20000,0xc40000,0xc70000,0xc90000,0xcb0000,0xce0000,0xd00000,0xd20000,0xd50000,0xd70000,0xd90000,0xdc0000,0xde0000,0xe00000,0xe30000,0xe50000,0xe70000,0xea0000,0xec0000,0xee0000,0xf10000,0xf30000,0xf50000,0xf80000,0xfa0000,0xfc0000,0xff0000,0xff0300,0xff0700,0xff0b00,0xff0f00,0xff1300,0xff1700,0xff1b00,0xff1f00,0xff2300,0xff2700,0xff2b00,0xff2f00,0xff3300,0xff3700,0xff3b00,0xff3f00,0xff4300,0xff4700,0xff4b00,0xff4f00,0xff5300,0xff5700,0xff5b00,0xff5f00,0xff6300,0xff6700,0xff6b00,0xff6f00,0xff7300,0xff7700,0xff7b00,0xff7f00,0xff8300,0xff8700,0xff8b00,0xff8f00,0xff9300,0xff9700,0xff9b00,0xff9f00,0xffa300,0xffa700,0xffab00,0xffaf00,0xffb300,0xffb700,0xffbb00,0xffbf00,0xffc300,0xffc700,0xffcb00,0xffcf00,0xffd300,0xffd700,0xffdb00,0xffdf00,0xffe300,0xffe700,0xffeb00,0xffef00,0xfff300,0xfff700,0xfffb00,0xffff00,0xffff03,0xffff07,0xffff0b,0xffff0f,0xffff13,0xffff17,0xffff1b,0xffff1f,0xffff23,0xffff27,0xffff2b,0xffff2f,0xffff33,0xffff37,0xffff3b,0xffff3f,0xffff43,0xffff47,0xffff4b,0xffff4f,0xffff53,0xffff57,0xffff5b,0xffff5f,0xffff63,0xffff67,0xffff6b,0xffff6f,0xffff73,0xffff77,0xffff7b,0xffff7f,0xffff83,0xffff87,0xffff8b,0xffff8f,0xffff93,0xffff97,0xffff9b,0xffff9f,0xffffa3,0xffffa7,0xffffab,0xffffaf,0xffffb3,0xffffb7,0xffffbb,0xffffbf,0xffffc3,0xffffc7,0xffffcb,0xffffcf,0xffffd3,0xffffd7,0xffffdb,0xffffdf,0xffffe3,0xffffe7,0xffffeb,0xffffef,0xfffff3,0xfffff7,0xfffffb]; private var particles:Array; private var temperature:Array; private var buffer:BitmapData; private var matrix:Matrix; public function Burn() { particles = new Array; temperature = new Array; for(var i:int = 0; i < W*H; i++) { temperature.push(0); } buffer = new BitmapData(W, H, false, 0x000000); for(var y:int = 0; y < H; y++) { for(var x:int = 0; x < W; x++) { buffer.setPixel(x, y, palette[temperature[y*W+x]]); } } var root:Sprite = new Sprite(); addChild(root); root.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); var image:Bitmap = new Bitmap(buffer); image.scaleX = 465 / W; image.scaleY = 465 / W; image.smoothing = true; matrix = image.transform.matrix; matrix.invert(); root.addChild(image); addEventListener(Event.ENTER_FRAME, onEnterFrame); for(var p:int = 0; p < 16; p++) { particles.push(new Particle(W/2 + Math.random() * 6 - 3, H/2 + Math.random() * 6 - 3, 3, Math.random() * 64 + 128)); } for(p = 0; p < 16; p++) { particles.push(new Particle(W/4 + Math.random() * 6 - 3, H/4 + Math.random() * 6 - 3, 3, Math.random() * 64 + 128)); } for(i = 0; i < 4; i++) { step(); blur(); } for(p = 0; p < 16; p++) { particles.push(new Particle(W/2 + Math.random() * 6 - 3, H*3/4 + Math.random() * 6 - 3, 3, Math.random() * 64 + 128)); } } private function onEnterFrame(evt:Event):void { step(); blur(); buffer.lock(); for(var y:int = 0; y < H; y++) { for(var x:int = 0; x < W; x++) { buffer.setPixel(x, y, palette[Math.min(int(temperature[y*W+x]), 255)]); } } buffer.unlock(); } private function onMouseDown(evt:MouseEvent):void { var p:Point = matrix.transformPoint(new Point(evt.localX, evt.localY)); for(var i:int = 0; i < 16; i++) { particles.push(new Particle(p.x + Math.random() * 6 - 3, p.y + Math.random() * 6 - 3, 3, Math.random() * 96 + 96)); } } private function step():void { for each(var p:Particle in particles) { p.step(1.0); if(p.isAlive()) { var i:int = int(p.getX()) + int(p.getY()) * W; temperature[i] += p.age; } } while(particles.length > 0 && !particles[0].isAlive()) { particles.shift(); } } private function blur():void { for(var y:int = 0; y < H - 1; y++) { for(var x:int = 1; x < W; x++) { var xy:int = x + y * W; var c:Number = ( temperature[xy - 1] + temperature[xy + 1] + temperature[xy] + temperature[xy + W] ) / 4; temperature[xy] = c; } } for(var i:int = 0; i < temperature.length; i++) { temperature[i] = temperature[i] * 127 / 128; } } } } class Particle { private var x:Number, y:Number, vx:Number, vy:Number; public var age:Number; private static const G:Number = 0.05; public function Particle(x0:Number, y0:Number, r:Number, age0:Number) { x = x0; y = y0; var s:Number = (Math.random() * 1.0 / 3.0 + 1.0 / 3.0) * Math.PI; var t:Number = (Math.random() + 0.5) * Math.PI; vx = r * Math.cos(s) * Math.sin(t); vy = r * Math.sin(s) * Math.cos(t); age = age0; } public function step(d:Number) : void { x += vx * d; y += vy * d; vy += G * d; vx *= (31 / 32); vy *= (31 / 32); age -= 4; } public function isAlive() : Boolean { return age > 0; } public function getX() : Number { return x; } public function getY() : Number { return y; } } Burn