//////////////////////////////////////////////////////////////////////////////// // LightFolium + SoundMixer //////////////////////////////////////////////////////////////////////////////// package { import flash.display.Sprite; import flash.display.Shape; import flash.events.Event; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundLoaderContext; import flash.media.SoundMixer; import flash.utils.ByteArray; import flash.net.URLRequest; import flash.geom.Rectangle; [SWF(backgroundColor="#000000", width="465", height="465", frameRate="30")] public class Main extends Sprite { private var flare:FlareMap; private var detection:DetectPixels; private static var max:uint = 256; private static var cx:int = 232; private static var cy:int = 250; private static var fw:uint = 340; private static var fh:uint = 360; private static var tw:uint = 320; private static var th:uint = 320; private var area:Rectangle; private var folium:Sprite; private var lights:Array; // private var sound:Sound; private var channel:SoundChannel; private static var soundPath:String = "http://www.takasumi-nagai.com/soundfiles/sound001.mp3"; private var byteArray:ByteArray; private static var channels:uint = 256; public function Main() { Wonderfl.capture_delay(11); init(); } private function init():void { graphics.beginFill(0x000000); graphics.drawRect(0, 0, 465, 465); graphics.endFill(); // folium = new Sprite(); addChild(folium); folium.x = cx - fw*0.5; folium.y = fh - th; lights = new Array(); for (var n:uint = 0; n < max; n++) { var light:LightFolium = new LightFolium(); var angle:Number = 360/max*n; light.init(fw*0.5, cy - fh + th, angle); folium.addChild(light); light.fly(200, 1, 2, 2); lights.push(light); } var rect:Rectangle = new Rectangle(0, 0, fw, fh); flare = new FlareMap(rect); addChild(flare); flare.x = cx; flare.y = fh; area = new Rectangle(0, 0, tw, th); detection = new DetectPixels(4); detection.search(folium, area, 0x66FFFFFF); flare.map = detection.pixels(); flare.offset = {x: 0, y: fh - th}; //flare.setup(6, 2, 60); flare.setup(8, 2, 64); flare.start(); // sound = new Sound(); sound.addEventListener(Event.COMPLETE, complete, false, 0, true); sound.load(new URLRequest(soundPath), new SoundLoaderContext(10, true)); byteArray = new ByteArray(); } private function complete(evt:Event):void { evt.target.removeEventListener(Event.COMPLETE, complete); start(); } private function start():void { channel = sound.play(0, 1000); addEventListener(Event.ENTER_FRAME, update, false, 0, true); } private function update(evt:Event):void { detection.search(folium, area, 0x66FFFFFF); flare.map = detection.pixels(); // SoundMixer.computeSpectrum(byteArray, true, 32); for (var n:uint = 0; n < channels*2; n++) { var light:LightFolium = lights[n%channels]; var p:Number = byteArray.readFloat(); light.fly(200, 1, p*100 + 2, p*100 + 2); } } } } import flash.display.Sprite; import flash.geom.ColorTransform; import flash.events.Event; class LightFolium extends Sprite { private var light:Light; private var blink:Number; private var b:Number; private var trans:ColorTransform; private var tx:Number; private var ty:Number; private var cx:Number; private var cy:Number; private var r:Number; private var angle:Number; private var a:Number; private var nx:Number; private var ny:Number; private static var radian:Number = Math.PI/180; private static var deceleration:Number = 0.2; public function LightFolium() { light = new Light(); addChild(light); } public function init(x:int, y:int, a:Number):void { this.x = cx = x; this.y = cy = y; angle = a; } public function fly(r:Number, a:Number, nx:Number, ny:Number, dec:Number = 0.2):void { this.r = r; this.a = a; this.nx = nx; this.ny = ny; deceleration = dec; addEventListener(Event.ENTER_FRAME, flying, false, 0, true); } private function flying(evt:Event):void { angle += a; tx = cx + r*Math.sin(angle*nx*radian)*Math.cos(angle*radian); ty = cy + r*Math.sin(angle*ny*radian)*Math.sin(angle*radian); x += (tx - x)*deceleration; y += (ty - y)*deceleration; } } import flash.display.Shape; import flash.geom.Matrix; import flash.display.GradientType; class Light extends Shape { private static var center:Number = 2.5; private static var light:uint = 10; private static var color:uint = 0xFFFFFF; public function Light() { draw(); } private function draw():void { graphics.beginFill(color); graphics.drawCircle(0, 0, center); graphics.endFill(); var colors:Array = [color, color]; var alphas:Array = [0.6, 0]; var ratios:Array = [0, 255]; var matrix:Matrix = new Matrix(); matrix.createGradientBox(light*2, light*2, 0, -light, -light); graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix); graphics.drawCircle(0, 0, light); graphics.endFill(); } } import flash.display.Sprite; import flash.display.Shape; import flash.display.BitmapData; import flash.display.Bitmap; import flash.events.Event; import flash.geom.Rectangle; import flash.geom.Point; import flash.filters.BlurFilter; import flash.display.BlendMode; //import sketchbook.colors.ColorUtil; class FlareMap extends Sprite { private var rect:Rectangle; private var fire:Rectangle; private var flare:BitmapData; private var bitmapData:BitmapData; private var bitmap:Bitmap; private var rPalette:Array; private var gPalette:Array; private var bPalette:Array; private static var point:Point = new Point(0, 0); private var speed:Point = new Point(0, -6); private var unit:uint = 8; private var segments:uint = 8; private var blur:BlurFilter; private var mapList:Array; public var offset:Object = {x: 0, y: 0}; private var faded:uint = 0; public static const COMPLETE:String = Event.COMPLETE; public function FlareMap(r:Rectangle) { rect = r; initialize(); draw(); } public function setup(s:uint = 6, u:uint = 8, seg:uint = 8):void { speed.y = - s; unit = u; segments = seg; } public function set map(list:Array):void { mapList = list; } private function initialize():void { rPalette = new Array(); gPalette = new Array(); bPalette = new Array(); for (var n:uint = 0; n < 256; n++) { var luminance:uint = (n < 128) ? n*2 : 0; //var rgb:Object = ColorUtil.HLS2RGB(n*360/256, luminance, 100); var rgb:Object = HLS2RGB(n*360/256, luminance, 100); var color:uint = rgb.r << 16 | rgb.g << 8 | rgb.b; rPalette[n] = color; gPalette[n] = 0; bPalette[n] = 0; } blur = new BlurFilter(2, 8, 3); blendMode = BlendMode.ADD; } private function draw():void { fire = new Rectangle(0, 0, rect.width, rect.height + 10); flare = new BitmapData(fire.width, fire.height, false, 0xFF000000); bitmapData = new BitmapData(rect.width, rect.height, false, 0xFF000000); bitmap = new Bitmap(bitmapData); addChild(bitmap); bitmap.x = - rect.width*0.5; bitmap.y = - rect.height; } public function start():void { addEventListener(Event.ENTER_FRAME, apply, false, 0, true); } private function apply(evt:Event):void { if (!mapList) return; flare.lock(); bitmapData.lock(); for (var n:uint = 0; n < segments; n++) { var id:uint = Math.random()*mapList.length; var px:int = mapList[id].x + offset.x; var py:int = mapList[id].y + offset.y; var range:Rectangle = new Rectangle(px, py, unit, 2) flare.fillRect(range, 0xFFFFFF); } flare.applyFilter(flare, fire, speed, blur); bitmapData.paletteMap(flare, rect, point, rPalette, gPalette, bPalette); flare.unlock(); bitmapData.unlock(); } private function clear(evt:Event):void { faded ++; flare.lock(); bitmapData.lock(); flare.applyFilter(flare, fire, speed, blur); bitmapData.paletteMap(flare, rect, point, rPalette, gPalette, bPalette); if (faded > 20) { bitmapData.fillRect(rect, 0x000000); removeEventListener(Event.ENTER_FRAME, clear); dispatchEvent(new Event(FlareMap.COMPLETE)); } flare.unlock(); bitmapData.unlock(); } private function createEggMask(target:Shape):void { var w:Number = rect.width; var h:Number = rect.height*1.5; target.graphics.beginFill(0xFFFFFF); target.graphics.moveTo(-w*0.5, -h*0.2); target.graphics.curveTo(-w*0.4, -h, 0, -h); target.graphics.curveTo(w*0.4, -h, w*0.5, -h*0.2); target.graphics.curveTo(w*0.5, 0, 0, 0); target.graphics.curveTo(-w*0.5, 0, -w*0.5, -h*0.2); target.graphics.endFill(); } private function HLS2RGB(h:Number, l:Number, s:Number):Object{ var max:Number; var min:Number; h = (h < 0)? h % 360+360 : (h>=360)? h%360: h; l = (l < 0)? 0 : (l > 100)? 100 : l; s = (s < 0)? 0 : (s > 100)? 100 : s; l *= 0.01; s *= 0.01; if (s == 0) { var val:Number = l*255; return {r:val, g:val, b:val}; } if (l < 0.5) { max = l*(1 + s)*255; } else { max = (l*(1 - s) + s)*255; } min = (2*l)*255 - max; return _hMinMax2RGB(h, min, max); } private function _hMinMax2RGB(h:Number, min:Number, max:Number):Object{ var r:Number; var g:Number; var b:Number; var area:Number = Math.floor(h/60); switch(area){ case 0: r = max; g = min + h * (max - min)/60; b = min; break; case 1: r = max - (h - 60)*(max - min)/60; g = max; b = min; break; case 2: r = min ; g = max; b = min + (h - 120)*(max - min)/60; break; case 3: r = min; g = max - (h - 180)*(max - min)/60; b =max; break; case 4: r = min + (h - 240)*(max - min)/60; g = min; b = max; break; case 5: r = max; g = min; b = max - (h - 300)*(max - min)/60; break; case 6: r = max; g = min + h*(max - min)/60; b = min; break; } r = Math.min(255, Math.max(0, Math.round(r))); g = Math.min(255, Math.max(0, Math.round(g))); b = Math.min(255, Math.max(0, Math.round(b))); return {r:r, g:g, b:b}; } } import flash.display.BitmapData; import flash.geom.Rectangle; import flash.geom.Point; import flash.geom.Matrix; import flash.display.IBitmapDrawable; class DetectPixels { private var bd:IBitmapDrawable; private var rect:Rectangle; private var map:BitmapData; private var mapList:Array; private var accuracy:uint; private var threshold:uint = 0x80FFFFFF; public function DetectPixels(a:uint = 1) { accuracy = a; } public function search(t:IBitmapDrawable, r:Rectangle, th:uint = 0x80FFFFFF):void { bd = t; rect = r; threshold = th; var w:uint = rect.width/accuracy; var h:uint = rect.height/accuracy; detect(w, h); } private function detect(w:uint, h:uint):void { map = new BitmapData(w, h, true, 0x00000000); var matrix:Matrix = new Matrix(); matrix.translate(-rect.x, -rect.y); matrix.scale(1/accuracy, 1/accuracy); map.lock(); map.draw(bd, matrix); map.unlock(); mapList = new Array(); for (var x:uint = 0; x < w; x++) { for (var y:uint = 0; y < h; y++) { var color:uint = map.getPixel32(x, y); if (color >= threshold) { var px:int = x*accuracy + rect.x; var py:int = y*accuracy + rect.y; var point:Point = new Point(px, py); mapList.push(point); } } } } public function pixels():Array { return mapList; } } LightFolium + SoundMixer