In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: forked from: Musical Dots

/**
 * Copyright zetaliang ( http://wonderfl.net/user/zetaliang )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uQCM
 */

// forked from shodai910's forked from: Musical Dots
// forked from royi's Musical Dots
package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.BlurFilter;
    import flash.geom.Point;
    import flash.media.Sound;
    import flash.media.SoundMixer;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;
    import flash.utils.flash_proxy;
    import flash.utils.getTimer;
    
    [SWF(BackgroundColor=0x000000, width=465, height=465, frameRATE=60 )]
    public class A05MusicalDots extends Sprite{
        
        private var pos:int = 0;
        private var sw:int, sh:int;
        private var playSound:Boolean = true;
        private var vol:Number = .5;
        private var note:Number = 400;
        
        
        private var particles:Array = [];
        private var numParticles:uint = 10;
        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 notes:Array;
        private var notesCp:Array;
        private var playing:Boolean = false;
        
        // 音階:Scale
        private var sc:Object;
        
        public function A05MusicalDots() {
            sc = new Object();
            sc = {C:523, D:583, E:659, F:698, G:783, A:880,B:988}
            
            // 画面の幅、高さを取得
            sw = stage.stageWidth, sh = stage.stageHeight;
            // きらきら星のメロディ
            notes = [sc.C,sc.C,sc.G,sc.G,sc.A,sc.A,sc.G,
                     sc.F,sc.F,sc.E,sc.E,sc.D,sc.D,sc.C,
                     sc.G,sc.G,sc.F,sc.F,sc.E,sc.E,sc.D,
                     sc.G,sc.G,sc.F,sc.F,sc.E,sc.E,sc.D,
                     sc.C,sc.C,sc.G,sc.G,sc.A,sc.A,sc.G,
                     sc.F,sc.F,sc.E,sc.E,sc.D,sc.D,sc.C];
            notes.reverse();
            // 連続再生用にコピー
            notesCp = notes.concat();
            
            // キャンバスの作成
            // BitmapData(幅, 高さ, 透明度, 塗りの色)
            bmpData = new BitmapData(sw, sh, false, 0x000000);  
            // Bitmap(BitmapDataインスタンス, ピクセル吸着, スムージング)
            var bmp:Bitmap = new Bitmap(bmpData, "never", true); 
            addChild(bmp);
            
            // 画面に波形とパーティクルの設置
            waveGfx     = waveSprite.graphics;
            particleGfx = particleSprite.graphics;
            addChild(waveSprite);
            addChild(particleSprite);
            
            // ぼかしの設定
            // BlurFilter(水平方向ぼかし量, 垂直方向ぼかし量, 品質)
            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
                };
            }
            
            // 音関係
            var sound:Sound = new Sound();
            sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
            sound.play();
            
            // 画面クリック
            stage.addEventListener(MouseEvent.CLICK, onClick);
            
            // 毎フレーム
            addEventListener(Event.ENTER_FRAME, loop);
        }
        
        // パーティクルの描画
        private function loop(evt: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;
                
                // パーティクルの色と形指定
                // Graphics.begenFill(塗りの色)
                particleGfx.beginFill(0x00ffff);
                // Graphics.drawCircle(中心のx座標, 中心のy座標, 半径)
                particleGfx.drawCircle(particles[i].x, particles[i].y, 2); 
                particleGfx.endFill();
            }
            // パーティクルの描画
            bmpData.draw(particleSprite);
            // 波形の描画
            bmpData.draw(waveSprite);
            // ぼかし用フィルタの設定
            // BitmapData.applyFilter(ソースイメージ, 適用範囲, 適用位置, フィルタ効果)
            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);
            // 距離150pxを基準として線を描画する
            var distance:int = 150;
            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;
                
                // 線の設定
                // Graphics.lineStayle(太さ, 色, 透明度)
                particleGfx.lineStyle(1, 0xfffffff , 1 - (dist / distance));
                // 始点の設定 Graphics.moveTo(始点のx座標, 始点のy座標)
                particleGfx.moveTo(p1.x, p1.y);
                // 終点まで線を描画 Graphics.LineTo(終点の)
                particleGfx.lineTo(p2.x, p2.y);
                
                // 距離が30未満のとき音を鳴らす
                if(!playing && dist < 30) {
                    playing = true;
                    
                    // 連続出力用にメロディのコピーを作成
                    if(notesCp.length == 0) {
                        notesCp = notes.concat();
                    }
                    note = notesCp.pop();
                    pos = 0;
                    vol = .5;
                    
                    // 音がなった箇所の線を赤に
                    particleGfx.lineStyle(7, 0xff0000, 1- (dist / distance));
                    particleGfx.moveTo(p1.x, p1.y);
                    particleGfx.lineTo(p2.x, p2.y);
                }
            }
        }
        
        // 音関連の設定
        private function onSampleData(evt:SampleDataEvent):void {
            const RATE:int = 44100;
            const BUFFER:int = 2048;
            
            // 垂直線の描画
            waveGfx.clear();
            waveGfx.lineStyle(0, Math.random() * 0xffffff);
            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;
                
                // 音声出力
                evt.data.writeFloat(sample); // left
                evt.data.writeFloat(sample); // right
                
                // 波形の描画
                waveGfx.lineTo((i / BUFFER) * sw, (sh * .5) - (sample * sh));
            }
            
            // 音が小さくなったら音声出力終了
            if(vol < .0001) {
                playing = false;
            }
        }
        
        // クリック時、パーティクルを増やす
        private function onClick(evt:MouseEvent):void {
            particles.push(particles.length);
            particles[particles.length - 1] = {
                x:Math.random() * sw,
                    y:Math.random() * sh,
                    vx:Math.random() * 2 - 1,
                    vy:Math.random() * 2 - 1
            };
            
            numParticles++;
        }
    }
}