Musical Dots
/**
* Copyright royi ( http://wonderfl.net/user/royi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/v2jB
*/
package {
import flash.text.TextFormat;
import flash.text.TextField;
import flash.geom.Point;
import flash.filters.BlurFilter;
import flash.display.*;
import flash.events.*;
import flash.utils.getTimer;
import flash.media.SoundMixer;
import flash.media.Sound;
[SWF(width=465, height=465, frameRate=60, backgroundColor=0x000000)]
public class Main extends Sprite {
private var rate:int = 44100;
private var pos:int = 0;
private var buffer:int = 2048;
private var sound:Sound = new Sound();
private var sw:int, sh:int;
private var playSound:Boolean = true;
private var vol:Number = .5;
private var note:Number = 440;
private var particles:Array = [];
private var numParticles:int = 5;
private var distance:int = 150;
private var particleGfx:Graphics;
private var waveGfx:Graphics;
private var bmpData:BitmapData;
private var particleSprite:Sprite = new Sprite();
private var waveSprite:Sprite = new Sprite();
private var blur:BlurFilter;
private var debug:TextField = new TextField();
private var notes:Array;
private var playing:Boolean = false;
public function Main() {
sw = stage.stageWidth, sh = stage.stageHeight;
//notes = [440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880];
notes = [440, 494, 554, 622, 698, 784, 880, 988, 1109];
bmpData = new BitmapData(sw, sh, false, 0x000000);
var bmp:Bitmap = new Bitmap(bmpData, "never", true);
addChild(bmp);
addChild(waveSprite);
addChild(particleSprite);
particleGfx = particleSprite.graphics;
waveGfx = waveSprite.graphics;
blur = new BlurFilter(12, 12, 1);
for (var i:int = 0; i < numParticles; i++) {
particles[i] = {x:Math.random() * sw,
y:Math.random() * sh,
vx:Math.random() * 2 - 1,
vy:Math.random() * 2 - 1};
}
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
sound.play();
stage.addEventListener(MouseEvent.CLICK, onClick);
addEventListener(Event.ENTER_FRAME, loop);
debug.defaultTextFormat = new TextFormat("Arial", 11, 0x7777ff);
debug.autoSize = "left";
addChild(debug);
}
private function loop(e:Event):void {
particleGfx.clear();
for (var i:int = 0; i < numParticles; i++) {
for (var j:int = i+1; j < numParticles; j++) {
react(particles[i], particles[j]);
}
if (particles[i].vx > 1) particles.vx *= .99;
if (particles[i].vy > 1) particles.vy *= .99;
particles[i].x += particles[i].vx;
particles[i].y += particles[i].vy;
if (particles[i].x > sw) particles[i].x = 0;
if (particles[i].x < 0) particles[i].x = sw;
if (particles[i].y > sh) particles[i].y = 0;
if (particles[i].y < 0) particles[i].y = sh;
particleGfx.beginFill(0xffffff);
particleGfx.drawCircle(particles[i].x, particles[i].y, 2);
particleGfx.endFill();
}
bmpData.draw(particleSprite);
bmpData.draw(waveSprite);
bmpData.applyFilter(bmpData, bmpData.rect, new Point(), blur);
var time:int = getTimer();
bmpData.scroll(Math.cos(time*.001)*2.9, Math.sin(time*.001)*2.9);
}
private function react(p1:Object, p2:Object):void {
var dx:Number = p2.x - p1.x;
var dy:Number = p2.y - p1.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
if (dist < distance) {
var vx:Number = dx * .0005;
var vy:Number = dy * .0005;
p1.vx += vx;
p1.vy += vy;
p2.vx -= vx;
p2.vy -= vy;
particleGfx.lineStyle(1, 0xffffff, 1 - (dist / distance));
particleGfx.moveTo(p1.x, p1.y);
particleGfx.lineTo(p2.x, p2.y);
if (!playing && dist < 30) {
onClick(null);
particleGfx.lineStyle(7, 0xff0000, 1 - (dist / distance));
particleGfx.moveTo(p1.x, p1.y);
particleGfx.lineTo(p2.x, p2.y);
}
}
}
private function onSampleData(e:SampleDataEvent):void {
waveGfx.clear();
waveGfx.lineStyle(0, Math.random() * uint.MAX_VALUE);
waveGfx.moveTo(0, sh * .5);
for (var i:int = 0; i < buffer; i++) {
var phase:Number = (pos / rate) * (Math.PI * 2);
pos++;
var sample:Number = Math.sin(phase * note) * vol;
vol *= .9997;
e.data.writeFloat(sample); // left
e.data.writeFloat(sample); // right
waveGfx.lineTo( (i / buffer) * sw, (sh * .5) - (sample * sh) );
}
if (vol < .0001) {
playing = false;
}
}
private function onClick(e:MouseEvent):void {
if (!playing) {
playing = true;
note = notes[int(Math.random() * notes.length)];
pos = 0;
vol = .5;
}
}
}
}