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

Water Speach (inspired "Warter Talks") [Google API]

///////////////////////////////////////////////////
*     FireFoxで見てください
*
/**
 * Copyright romatica ( http://wonderfl.net/user/romatica )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/x36H
 */

/*
 * ///////////////////////////////////////////////////
 *     FireFoxで見てください( ´д`; ) 
 * ///////////////////////////////////////////////////
 * 
 * [ "WARTER SPEACH" ] Google API
 * スペース区切りで入力したテキストが、
 * 1単語づつ、Speach & Drop。
 * 
 *  
 * Safari/ChromeなどWebkit系からだと、音声が読み込めないそうです。
 * @see http://twitter.com/clockmaker_core/status/14569180544
 * 
 * また、同じくWebkit系だと最初の1単語しか表示されない。。。
 * FireFoxで見てください( ´д`; ) 
 * 
 * TODO:スペースを2つ続けるとバグる。あとでなおす(かも)。
 * TODO:webkit系でもなんとかできないか調べる。
 * 
 * @auther itoz(www.romatica.com)
 *
 * -----------------------
 *    ["Water Talks"] に Inspire。
 *    @see http://vimeo.com/10756110
 *    
 * -----------------------
 * 
 *    "clock_marker"さんと"Saqoosha"さんのCODEをがっちゃんこ。
 *     @see http://wonderfl.net/c/rgyc/  [clock_marker:Text speech by Google API]
 *    @see http://wonderfl.net/c/25ff/  [Saqoosha:Rainy Day]
 * 
 * 
 */
package {
    import com.bit101.components.InputText;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.filters.BlurFilter;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.Point;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.Timer;

    [SWF(width=465, height=465, backgroundColor=0x0, frameRate=120)]

    public class WaterSpeach extends Sprite {

        private static const GRAVITY     : Number = 20;
        private static const ZERO_POINT : Point = new Point( 0, 0 );
        private var _canvas             : BitmapData;
        private var _drop                 : Vector.<SnowParticle>;
        private var _blur                 : BlurFilter = new BlurFilter( 1.5, 1.5, 1 );
        private var _input                : InputText;
        private var _splitArr            : Array =[];
        private var _tBMDArr             : Array;
        private var _sndArr             : Array;
        private var _timer                 : Timer;
        private var _channel            : SoundChannel;
        private var speachLineCount     : int = 0;
        private var lineY                 : int;
        private var _color                 : ColorMatrixFilter;
        public function WaterSpeach() 
        {
            //Wonderfl.capture_delay(1 )

            //BG
            var BG:Sprite = addChild(new Sprite()) as Sprite;
            BG.graphics.beginFill(0x0);
            BG.graphics.drawRect(0,0,465,465);
            BG.graphics.endFill();
            _color= new ColorMatrixFilter( [ 1, 0, 0, 0, -5,
                                            0, 1, 0, 0, -5,
                                            0, 0, 1, 0, -5,
                                            0, 0, 0, 1, 0 ] );
            _canvas = new BitmapData( 465, 465, true, 0x0 );
            addChild( new Bitmap( this._canvas ) ) as Bitmap; 
            _drop = new Vector.<SnowParticle>( );

            // Text Input
            _input = new InputText( this, 50, 232, "Wonderful Build Flash Online", null );
            _input.width = 210;
            _input.maxChars = 90;
            
            // Button
            new PushButton( this, 270, 230, "WATER SPEACH", onClick );
            
                //Start
            setWaterSpeach();

        }

        private function onClick(e : MouseEvent=null) : void {
            setWaterSpeach();
        }
        
        private function setWaterSpeach() : void 
        {
                       
            reset( );
            _splitArr = [];
            _tBMDArr = [];
            _sndArr = [];
            //split
            _splitArr = _input.text.split( " " );
            //入力テキストビットマップ化
            createBitmaps( );
            // サウンド作成
            createSound( );
            //スピーチスタート
            startSpeati( );
            //レンダリング
            addEventListener( Event.ENTER_FRAME, this.update ); 
        }
        /**
         *再入力時のリセット 
         */
        private function reset() : void
        {
            if(hasEventListener( Event.ENTER_FRAME )) {
                addEventListener( Event.ENTER_FRAME, this.update ); 
            }
            crearChannel( );
            crearTimer( );
            for (var i : int = 0; i < _splitArr.length; i++) {
                _sndArr[i] = null;
                _tBMDArr[i].dispose( );
                _tBMDArr[i] = null;
            }
        }
        /**
         * sound 作成し保管
         */
        private function createSound() : void 
        {
            for (var i : int = 0; i < _splitArr.length; i++) {
                var req : URLRequest = new URLRequest( "http://translate.google.com/translate_tts" + "?tl=en" + "&q=" + String( _splitArr[i] ) );
                var snd : Sound = new Sound( req );
                _sndArr.push( snd );
            }
        }
        /**
         * bitmap 作成し保管
         */
        private function createBitmaps() : void 
        {
            for (var i : int = 0; i < _splitArr.length; i++) {
                var tf : TextField = new TextField( );
                tf.defaultTextFormat = new TextFormat( null, 90, 0xffffff, true ); 
                tf.autoSize = TextFieldAutoSize.LEFT;
                tf.text = _splitArr[i];
                tf.x = (465 - tf.width) / 2;
                var tBMD : BitmapData = new BitmapData( 465, tf.height, true, 0x0 );
                tBMD.draw( tf, tf.transform.matrix );
                _tBMDArr.push( tBMD );
            }
        }

        /**
         * one word speach start
         */
        private function startSpeati(e : TimerEvent = null) : void 
        {
            //trace( 'startSpeati: ' + (_splitArr[speachLineCount]) );
            lineY = _tBMDArr[speachLineCount].height;
            crearChannel( );
            _channel = _sndArr[speachLineCount].play( 0, 1 );
            _channel.addEventListener( Event.SOUND_COMPLETE, SoundCompFunc );
        }
        /**
         * sound channel crear
         */
        private function crearChannel() : void
        {
            if(_channel != null) {
                if(_channel.hasEventListener( Event.SOUND_COMPLETE )) {
                    _channel.removeEventListener( Event.SOUND_COMPLETE, SoundCompFunc );
                }
                _channel = null;
            }
        }

        /**
         * one word speach fix
         */
        private function SoundCompFunc(event : Event) : void 
        {
            //trace( "1word最後まで再生された " + _splitArr [speachLineCount]);
            crearTimer( )
            //1秒後に次の単語再生
            _timer = new Timer( 1000, 1 );
            _timer.addEventListener( TimerEvent.TIMER, count );
            _timer.start( );
        }
        /**
         * timer clear
         */
        private function crearTimer() : void 
        {
            if(_timer != null) {
                if(_timer.hasEventListener( TimerEvent.TIMER )) {
                    _timer.removeEventListener( TimerEvent.TIMER, startSpeati );
                }
                _timer = null;
            }
        }
        /**
         * word count check
         */
        private function count(e : TimerEvent) : void
        {
            speachLineCount = (speachLineCount < _splitArr.length - 1) ? speachLineCount + 1 : 0;
            startSpeati( );
        }

        /**
         * DROP
         */
        public function update(e : Event) : void 
        {
            //Create 1 line 下から作成
            if(lineY > 0) {
                var xx : int = _tBMDArr[speachLineCount].width;
                for (var lineX : int = 0; lineX < xx; lineX += 4) {
                    if(_tBMDArr[speachLineCount].getPixel( lineX, lineY ) != 0) {
                        _drop.push( emitParticle( lineX, 0, Math.random( ) * 0.03 + 0.5 ) );
                    }
                }
                lineY -= 2;
            }
            
            //move
            _canvas.lock( ); 
            _canvas.applyFilter( this._canvas, this._canvas.rect, ZERO_POINT, this._color );
            _canvas.applyFilter( this._canvas, this._canvas.rect, ZERO_POINT, this._blur );
            var max : int = _drop.length;
            var gravity : Number = GRAVITY / 100; 
            while(max--) {    
                var p : SnowParticle = _drop[max];
                p.vy += gravity * p.s; // まず重力を加える
                p.y += p.vy;
                _canvas.setPixel32( p.x, p.y, p.c | ((1 * 0xff) << 24) );
                if (p.y > this.stage.stageHeight) { 
                    // もし画面外にでちゃったら とりのぞく
                    _drop.splice( max, 1 );
                }
            }
            _canvas.unlock( );
        }

        /** 
         *  create 1DROP
         */
        public function emitParticle(ex : Number, ey : Number, s : Number = 1, c : int = 0x00bfff, vx : Number = 0, vy : Number = 0) : SnowParticle 
        {
            var p : SnowParticle = new SnowParticle( );
            p.x = ex;
            p.y = ey;
            p.vx = vx;
            p.vy = vy;
            p.s = s;
            p.c = c;
            return p;
        }
    }
}

class SnowParticle {

    public var x : Number;
    public var y : Number;
    public var vx : Number;
    public var vy : Number;
    public var s : Number;
    public var c : int;

    public function SnowParticle() 
    {
        this.x = 0;
        this.y = 0;
        this.vx = 0;
        this.vy = 0;
        this.s = 1;
        this.c = 0xffffff;
    }
}