EmitLight (7)
////////////////////////////////////////////////////////////////////////////////
// EmitLight (7)
//
// 音はTsabeat より拝借
// http://www.ektoplazm.com/free-music/tsabeat-warp-speed-ep/
//
// 置き換えマップ効果 (3)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=480
// BitmapDataでノイズ生成 (3)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=481
// [AS3.0] PerlinNoiseクラスに挑戦!
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1114
//
// 動作を軽くするための方法 (東京てらこ7 @trick7)
// Bitmap.filters を使わず、BitmapData.applyFilter() を用いる
////////////////////////////////////////////////////////////////////////////////
/**
* Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/d3ob
*/
// forked from Event's Instrument
////////////////////////////////////////////////////////////////////////////////
// EmitLight (7)
//
// 音はTsabeat より拝借
// http://www.ektoplazm.com/free-music/tsabeat-warp-speed-ep/
//
// 置き換えマップ効果 (3)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=480
// BitmapDataでノイズ生成 (3)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=481
// [AS3.0] PerlinNoiseクラスに挑戦!
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1114
//
// 動作を軽くするための方法 (東京てらこ7 @trick7)
// Bitmap.filters を使わず、BitmapData.applyFilter() を用いる
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
[SWF(backgroundColor="#000000", width="465", height="465", frameRate="60")]
public class Main extends Sprite {
private var light:EmitLight;
private var water:WaterEffect;
private var faded:Boolean = true;
public function Main() {
//Wonderfl.capture_delay(4);
init();
}
private function init():void {
graphics.beginFill(0x000000);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill();
var rect:Rectangle = new Rectangle(0, 0, 465, 465);
light = new EmitLight(rect);
//addChild(light);
water = new WaterEffect(rect);
addChild(water);
water.addEventListener(WaterEffect.COMPLETE, complete, false, 0, true);
water.setup(light, null, 400);
water.wave();
}
private function complete(evt:Event):void {
var timer:Timer;
if (faded) {
timer = new Timer(3000, 1);
} else {
timer = new Timer(100, 1);
}
timer.addEventListener(TimerEvent.TIMER_COMPLETE, exchange, false, 0, true);
timer.start();
}
private function exchange(evt:TimerEvent = null):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, exchange);
faded = !faded;
if (faded) {
water.wave(0, 1);
} else {
water.wave(1, 0);
}
}
}
}
//////////////////////////////////////////////////
// WaterEffectクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.events.Event;
import flash.filters.DisplacementMapFilter;
import flash.display.BitmapDataChannel;
import flash.filters.DisplacementMapFilterMode;
import flash.filters.BlurFilter;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.events.TweenEvent;
import org.libspark.betweenas3.easing.Linear;
import org.libspark.betweenas3.easing.Quad;
class WaterEffect extends Sprite {
private var rect:Rectangle;
private var noise:PerlinNoise;
private static var octaves:uint = 1;
private static var channel:uint = BitmapDataChannel.RED;
private var speeds:Array;
private var target:DisplayObject;
private var container:Bitmap;
private var matrix:Matrix;
private var bitmapData:BitmapData;
private var mapfilter:DisplacementMapFilter;
private var blurfilter:BlurFilter;
private static var baseScale:Number;
private var _scale:Number = 0;
private var _size:Number = 0;
private static var time:Number = 1;
public static const COMPLETE:String = Event.COMPLETE;
public function WaterEffect(r:Rectangle) {
rect = r;
init();
}
private function init():void {
noise = new PerlinNoise(rect, 32, 32, octaves, false, channel);
speeds = new Array();
for (var n:uint = 0; n < octaves; n++) {
var sx:Number = (Math.random() - 0.5)*3;
var sy:Number = (Math.random() - 0.5)*3 + 2.5;
speeds.push(new Point(sx, sy));
}
bitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
container = new Bitmap(bitmapData);
addChild(container);
map = 0;
blur = 0;
}
public function setup(t:DisplayObject, m:Matrix = null, bs:Number = 0):void {
target = t;
matrix = m;
bitmapData.fillRect(rect, 0x00000000);
bitmapData.draw(target, matrix, null, null, null, true);
container.bitmapData = bitmapData.clone();
baseScale = bs;
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
}
public function wave(from:Number = 0, to:Number = 1):void {
tween(from, to);
}
private function tween(from:Number = 0, to:Number = 1):void {
var itween:ITween = BetweenAS3.parallel(
BetweenAS3.tween(container, {alpha: to}, {alpha: from}, time, Linear.easeNone),
BetweenAS3.tween(this, {map: to}, {map: from}, time, Quad.easeOut),
BetweenAS3.tween(this, {blur: to}, {blur: from}, time, Linear.easeNone)
);
itween.addEventListener(TweenEvent.COMPLETE, complete, false, 0, true);
itween.play();
}
private function update(evt:Event):void {
noise.update(speeds);
container.bitmapData.lock();
bitmapData.fillRect(rect, 0x00000000);
bitmapData.draw(target, matrix, null, null, null, true);
container.bitmapData.applyFilter(bitmapData, bitmapData.rect, new Point(), mapfilter);
container.bitmapData.applyFilter(container.bitmapData, bitmapData.rect, new Point(), blurfilter);
container.bitmapData.unlock();
}
private function complete(evt:TweenEvent):void {
dispatchEvent(new Event(COMPLETE));
}
public function get map():Number {
return _scale;
}
public function set map(param:Number):void {
_scale = param;
var scale:Number = baseScale*(1 - _scale);
mapfilter = new DisplacementMapFilter(noise, new Point(), channel, channel, scale, scale, DisplacementMapFilterMode.COLOR);
}
public function get blur():Number {
return _size;
}
public function set blur(param:Number):void {
_size = param;
var size:Number = baseScale*(1 - _size)/10;
blurfilter = new BlurFilter(size, size, 3);
}
}
//////////////////////////////////////////////////
// PerlinNoiseクラス
//////////////////////////////////////////////////
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.ColorTransform;
class PerlinNoise extends BitmapData {
private var bx:uint;
private var by:uint;
private var octaves:uint;
private var seed:uint;
private var stitch:Boolean = true;
private var fractalNoise:Boolean = true;
private var channel:uint = 0;
private var grayScale:Boolean = true;
private var offsets:Array = new Array();
public function PerlinNoise(rect:Rectangle, x:uint, y:uint, o:uint = 1, g:Boolean = true, c:uint = 0, s:uint = 1, st:Boolean = false, f:Boolean = true) {
super(rect.width, rect.height, false, 0xFF000000);
bx = x;
by = y;
octaves = o;
grayScale = g;
channel = c;
if (grayScale) channel = 0;
for (var n:uint = 0; n < octaves; n++) {
var point:Point = new Point();
offsets.push(point);
}
stitch = st;
fractalNoise = f;
create(s, offsets);
}
private function create(s:uint, o:Array = null):void {
seed = s;
offsets = o;
if (offsets == null) offsets = [new Point()];
lock();
perlinNoise(bx, by, octaves, seed, stitch, fractalNoise, channel, grayScale, offsets);
draw(this);
unlock();
}
public function update(speeds:Array):void {
for (var n:uint = 0; n < octaves; n++) {
var offset:Point = offsets[n];
var speed:Point = speeds[n];
offset.x += speed.x;
offset.y += speed.y;
}
lock();
perlinNoise(bx, by, octaves, seed, stitch, fractalNoise, channel, grayScale, offsets);
draw(this);
unlock();
}
}
//////////////////////////////////////////////////
// EmitLightクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.geom.ColorTransform;
import flash.display.BlendMode;
import flash.filters.BlurFilter;
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.system.Security;
import frocessing.color.ColorHSV;
class EmitLight extends Sprite {
private var rect:Rectangle;
private var bitmapData:BitmapData;
private var bitmap:Bitmap;
private var container:Sprite;
private static var max:uint = 4;
private var particles:Array;
private var color:ColorHSV;
private var colorTrans:ColorTransform;
private static var blur:BlurFilter;
private static var point:Point = new Point();
private var id:uint = 0;
private static var policyPath:String = "http://mutast.heteml.jp/crossdomain.xml";
private var sound:Sound;
private var channel:SoundChannel;
private static var soundPath:String = "http://mutast.heteml.jp/works/music/music.mp3";
private var byteArray:ByteArray;
private static var channels:uint = 256;
private var factors:uint = 0;
private static var radian:Number = Math.PI/180;
private static var radius:uint = 128;
public function EmitLight(r:Rectangle) {
rect = r;
init();
}
private function init():void {
bitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
bitmap = new Bitmap(bitmapData);
addChild(bitmap);
container = new Sprite();
addChild(container);
particles = new Array();
color = new ColorHSV(0);
colorTrans = new ColorTransform();
blur = new BlurFilter(8, 8, 3);
//
Security.loadPolicyFile(policyPath);
sound = new Sound();
sound.addEventListener(Event.COMPLETE, loaded, false, 0, true);
sound.load(new URLRequest(soundPath), new SoundLoaderContext(10, true));
byteArray = new ByteArray();
}
private function loaded(evt:Event):void {
evt.target.removeEventListener(Event.COMPLETE, loaded);
start();
}
private function start():void {
channel = sound.play(0, 1000);
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
}
private function update(evt:Event):void {
SoundMixer.computeSpectrum(byteArray, false, factors);
var units:Array = new Array();
for (var n:uint = 0; n < channels; n++) {
var p:Number = byteArray.readFloat();
if (n%32 == 0) units.push(p);
}
create(units);
draw();
}
private function draw():void {
bitmapData.lock();
for (var n:uint = 0; n < particles.length; n++) {
var particle:Particle = particles[n];
particle.update();
particle.scale = particle.alpha = particle.power;
if (particle.power < 0) {
container.removeChild(particle);
particles.splice(n, 1);
particle = null;
}
}
color.h = id;
colorTrans.color = color.value;
bitmapData.draw(container, null, colorTrans, BlendMode.SCREEN, null, true);
bitmapData.applyFilter(bitmapData, rect, point, blur);
bitmapData.unlock();
id ++;
}
private function create(units:Array):void {
for (var n:uint = 0; n < max; n++) {
var particle:Particle = new Particle();
var p:Number = units[n]*360 + 90;
particle.tx = 232 + radius*Math.cos(p*radian);
particle.ty = 232 + radius*Math.sin(p*radian);
particle.angle = Math.random()*360;
particle.speed = Math.random()*3 + 5;
particle.power = 1;
particle.setup();
container.addChild(particle);
particles.push(particle);
}
}
}
//////////////////////////////////////////////////
// Particleクラス
//////////////////////////////////////////////////
import flash.display.Shape;
class Particle extends Shape {
private static var radius:uint = 6;
private static var color:uint = 0xFFFFFF;
public var angle:Number = 0;
public var speed:Number = 0;
public var tx:Number;
public var ty:Number;
private var vx:Number = 0;
private var vy:Number = 0;
public var power:Number = 0;
private static var radian:Number = Math.PI/180;
private static var friction:Number = 0.96;
private static var deceleration:Number = 0.016;
private static var acceleration:Number = 0.02;
private var _scale:Number = 1;
public function Particle() {
draw();
}
private function draw():void {
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
public function setup():void {
x = tx;
y = ty;
vx = speed*Math.cos(angle*radian);
vy = speed*Math.sin(angle*radian);
}
public function update():void {
tx += vx;
ty += vy;
x += (tx - x)*acceleration;
y += (ty - y)*acceleration;
vx *= friction;
vy *= friction;
power -= deceleration;
}
public function get scale():Number {
return _scale;
}
public function set scale(param:Number):void {
_scale = param;
scaleX = scaleY = _scale;
}
}