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

dynamic sound generate. ボールに合わせる。

ボールのバウンドに合わせて。

音の遅延に対する処理は適当。
/**
 * Copyright sakef ( http://wonderfl.net/user/sakef )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vRq9
 */

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.SampleDataEvent;
    import flash.events.TimerEvent;
    import flash.media.Sound;
    import flash.utils.ByteArray;
    import flash.utils.Timer;
    
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="40")]
    public class Main extends Sprite
    {
        private static const SAMPLING:int = 2048;            // バッファ
        private static const SAMPLING_RATE:int = 44100;    // サンプリングレート
        private static const PI:Number = Math.PI * 2;        // 1周期
        private static const VOLUME:Number = 0.1;            // ボリューム
        private static const MAX:Number = 0.7;            // 音の最大値
        
        private var soundContainer:Array;
        private var ballContainer:Array;
        
        public function Main()
        {
            // コンテナ
            soundContainer = [];
            ballContainer = [];
            
            // タイマーの初期化
            var t:Timer = new Timer(1200);
            t.addEventListener(TimerEvent.TIMER, addBall);
            t.start();
            addEventListener(Event.ENTER_FRAME, onFrame);
            
            // サウンドの再生
            var sound:Sound = new Sound;
            sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
            sound.play();
        }
        
        // ボールの動きを制御する関数
        private function onFrame(e:Event):void
        {
            var len:int=ballContainer.length;
            while(len--)
            {
                var ball:Ball=ballContainer[len] as Ball;
                ball.render(soundContainer);
                
                if (ball.alpha <= 0)
                {
                    ballContainer.splice(len, 1);
                    removeChild(ball);
                    ball=null;
                }
            }
        }
        
        // ボールを加える関数
        private function addBall(e:TimerEvent):void
        {
            var ball:Ball=new Ball();
            addChild(ball);
            ballContainer.push(ball);
            ball.x = 465 / 2;
            ball.y = 465 / 2 - 50;
        }
        
        // 波形を書き込む
        private function onSampleData(e:SampleDataEvent):void
        {
            var data:ByteArray = e.data;
            var pos:Number = e.position;
            var len:int = soundContainer.length;
            var s:SoundData;
            var i:int, n:int;    
            
            for(i=0 ; i<SAMPLING ; i++)
            {
                var d:Number = 0;
                n = len;
                
                // データを足し合わせていく。
                while(n--)
                {
                    s = soundContainer[n] as SoundData;
                    var w:Number = (PI * s.frequency / SAMPLING_RATE);
                    var phase:Number = ((pos + i) * w) % PI;
                    var dd:Number;
                    if(phase < Math.PI) dd = 1 - 2*phase/Math.PI;
                    else dd = -1 + 2 * (phase - Math.PI)/Math.PI;
                    
                    d += dd*0.2*s.volume;
                }
                
                // データを範囲内に丸める
                d = (d > -0.8)?(d):(-0.8);
                d = (d < 0.8)?(d):(0.8);
                
                // 書き込み
                data.writeFloat(d);
                data.writeFloat(d);
            }
            
            n = soundContainer.length;
            while(n--)
            {
                s = (soundContainer[n] as SoundData);
                s.renderSound();
                if(s.state == 3) soundContainer.splice(n,1);    
            }
        }
    }
}

// 音データを保持するクラス
class SoundData
{
    public var frequency:Number;
    public var volume:Number;
    public var state:int;
    
    private var fadeIn:Number;
    private var fadeOut:Number;
    private var show:Number;
    private var volMax:Number;
    private var count:int;
    
    public function SoundData(frequency:Number, fadeIn:Number, fadeOut:Number, show:int, volMax:Number)
    {
        this.frequency = frequency;
        this.fadeIn = fadeIn;
        this.fadeOut = fadeOut;
        this.show = show;
        this.volMax = volMax;
        this.volume = this.state = this.count = 0
    }
    
    public function renderSound():void
    {
        switch(state)
        {
            // 音をフェードインさせる
            case 0:
                volume += fadeIn;
                if(volume>=volMax)
                {
                    volume = volMax;
                    state = 1;
                }
                break;
            
            // 音を流す
            case 1:
                count ++;
                if(count == show) state = 2;
                break;
            
            // 音をフェードアウトさせる
            case 2:
                volume -= fadeOut;
                if(volume <= 0)
                {
                    state = 3;
                    volume = 0;
                }
                break;
        }
    }
}


// ボールクラス
import flash.display.Shape;
class Ball extends Shape
{
    private static const COLOR:Array=[0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
    private static const COLOR_N:int=6;
    private static const DRAG:Number = 0.99;
    private static const GRAVITY:Number = 0.8;
    private var xvel:Number;
    private var yVel:Number;
    private var frequency:Number;
    private var prev:Number;
    
    public function Ball()
    {
        xvel=7 * Math.random() - 3.5;
        yVel=5;
        frequency = 440 * Math.pow(2, (int(20*Math.random()))/12);
        
        var c_index:int=COLOR_N * Math.random() >> 0;
        var color:uint=COLOR[c_index];
        graphics.beginFill(color, 1);
        graphics.drawCircle(0, 0, 20);
        graphics.endFill();
        prev = 0;
    }
    
    public function render(sound:Array):void
    {
        alpha-=0.005;
        x+=xvel;
        y+=yVel;
        yVel*=DRAG;
        yVel+=GRAVITY;
        scaleX=scaleY*=DRAG;
        
        if(y > 220 && prev < 220) sound.push(new SoundData(frequency, 0.5, 0.015, 2, alpha*0.5));    
        prev = y;
        
        if (y > 300)
        {
            y=300;
            yVel=-yVel * 0.99;
        }
    }
}