forked from: up to you

by Aksor.Al forked from up to you (diff: 3)
全3ステップ。
webカメラ必須です。 
エッチになるかどうかはあなた次第。

以下のコードを一部使用させていただきました。
動体検知 + 肌色認識
http://wonderfl.net/code/fca88ba91359931c2c466a7bdcacca9ef8be6fa4
Emotion Fractal in AS3(テキストサイズ取得)
http://wonderfl.net/code/fe30ff080634cc6c609e521f40276a32260acd99
♥0 | Line 870 | Modified 2011-01-04 14:13:29 | MIT License
play

ActionScript3 source code

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

// forked from buccchi's up to you
// forked from checkmate's Checkmate Vol.6 Amatuer
/*
 * 全3ステップ。
 * webカメラ必須です。 
 * エッチになるかどうかはあなた次第。
 *
 *
 * 以下のコードを一部使用させていただきました。
 * 動体検知 + 肌色認識
 * http://wonderfl.net/code/fca88ba91359931c2c466a7bdcacca9ef8be6fa4
 * Emotion Fractal in AS3(テキストサイズ取得)
 * http://wonderfl.net/code/fe30ff080634cc6c609e521f40276a32260acd99
 */
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    [SWF(width="465", height="465", backgroundColor="#000000", frameRate="30")]
    public class CheckmateAmatuer extends Sprite {
        private var _answers:Array;
        private var _homeWords:Array;
        private var _youkyuWords:Array;
        private var _typoWords:Array;
        private var _photos:Array;
        
        public function CheckmateAmatuer() {
            /*
            コードでエッチなものごとを描写してください。
            公序良俗は守ってください。
            
            Represent something sexual by codes.
            DO NOT be offensive to public order and morals.
            */
            init();
        }
        
        private function init():void {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            var intro1:Intro = new Intro(1, "PPP", "まずは5つの質問にお答えください。\n   クリックでスタート。", false);
            intro1.addEventListener(Event.COMPLETE, intro1Complete);
            addChild(intro1);
        }
        
        private function intro1Complete(e:Event):void {
            var questions:Array = ["ssssss",
                                    "自分の体、自信があるのはどのパーツ?",
                                    "異性に言われて興奮する言葉は?",
                                     "セクシーだと思う服装は?",
                                    "野球拳、どこまで脱げる?"];
            var step1:Step1 = new Step1(questions);
            step1.addEventListener(MyEvent.COMPLETE, step1Complete);
            addChild(step1);
        }
        
        private function step1Complete(e:MyEvent):void {
            _typoWords = e.v;
            var intro2:Intro = new Intro(2, "撮影", "webカメラを使ってあなたを撮影します。\n 動いたり止まったりしてください。");
            intro2.addEventListener(Event.COMPLETE, intro2Complete);
            addChild(intro2);
        }
        
        private function intro2Complete(e:Event):void {
            var sexJudgments:Array = ["男性", "男", "だんせい", "おとこ", "dansei", "otoko"]; 
            var catJudgments:Array = ["猫", "ネコ", "ねこ", "ぬこ", "オス", "メス"]; 
            _homeWords = [_typoWords[1]+"を強調してっ", _typoWords[2], "いいよ", "いいね", "もっと大胆に", "そうそう"];
            for(var i:uint=0; i< sexJudgments.length; i++){
                if(_typoWords[0] == sexJudgments[i]){
                    _homeWords.push("うほっ");
                    _homeWords.push("うほっ");
                    _homeWords.push("いい男");
                    break;
                }
            }
            for(var j:uint=0; j< catJudgments.length; j++){
                if(_typoWords[0] == catJudgments[j]){
                    _homeWords = [_typoWords[1]+"を強調するにゃ", _typoWords[2], "にゃー", "にゃ"];
                    break;
                }
            }
            _youkyuWords = ["もっとカメラに近づいて",
                            _typoWords[3]+"になってみようか",
                            _typoWords[4]+"脱いじゃおっか"];
            _youkyuWords.push("ラスト1枚");
            var step2:Step2 = new Step2(_homeWords, _youkyuWords);
            step2.addEventListener(MyEvent.COMPLETE, step2Complete);
            addChild(step2);
            _typoWords.shift();
        }
        
        private function step2Complete(e:MyEvent):void {
            _photos = e.v;
            var intro3:Intro = new Intro(3, "完成", "クリックするごとに写真が切り替わります。");
            intro3.addEventListener(Event.COMPLETE, intro3Complete);
            addChild(intro3);
        }
        
        private function intro3Complete(e:Event):void {
            var step3:Step3 = new Step3( _typoWords, _photos );
            addChild(step3);
        }
    }
}





import flash.display.Sprite;
//import flash.events.DataEvent;
import flash.events.Event;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.*;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.events.TweenEvent;

class Step1 extends Sprite {
    private var _t:ITween;
    private var _questions:Array;
    private var _questionStep:Number;
    private var _answers:Array;
    
    public function Step1(questions:Array) {
        addEventListener(Event.ADDED, init);
        _questions = questions;
    }
    private function init(e:Event):void {
        removeEventListener(Event.ADDED, init);
        _questionStep = 0;
        _answers = new Array();
        createForm();
    }
    private function createForm():void {
        var form:Sprite = new MyForm(_questionStep+1, _questions[_questionStep]);
        addChild(form);
        form.x = Math.floor(stage.stageWidth/2);
        var goalY:Number = Math.floor(stage.stageHeight/2 - form.height/2);
        _t = BetweenAS3.tween(form, { y:goalY }, { y:stage.stageHeight+10 }, 1, Cubic.easeInOut);
        _t.play();
        form.addEventListener(MyForm.COMPLETE, submit);
    }
    
    private function submit(e:DataEvent):void {
        _answers.push(e.data);
        //前のフォームをスクロールし削除
        var oldForm:Sprite = (e.target) as Sprite;
        if(_t != null) _t.stop();
        _t = BetweenAS3.tween(oldForm, { y:-oldForm.height-10 }, null, 1, Cubic.easeInOut);
        _t.addEventListener(TweenEvent.COMPLETE, function(e:TweenEvent):void {
            removeChild(oldForm);
        });
        _t.play();
        //次の質問の有無をチェック
        if(_questionStep < _questions.length-1){
            _questionStep++;
            createForm();
         }else{
            dispatchEvent( new MyEvent(MyEvent.COMPLETE, _answers) );
        }
    }
}





import flash.display.BitmapData;
import flash.display.Bitmap;
//import flash.display.Sprite;
import flash.display.BlendMode;
//import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.ActivityEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
import flash.media.Camera;
import flash.media.Video;
import flash.utils.Timer;
import flash.text.TextField;

class Step2 extends Sprite {
    private const NOISE_REDUCTION:ConvolutionFilter= new ConvolutionFilter(3, 3, [1,  1, 1,    1, 16, 1,    1,  1, 1], 1, -(0x1000 + 0x100 * 6));
    private const GRAY_SCALE:ColorMatrixFilter = new ColorMatrixFilter([
                                                            0.3, 0.59, 0.11, 0, 0,
                                                            0.3, 0.59, 0.11, 0, 0,
                                                            0.3, 0.59, 0.11, 0, 0,
                                                            0, 0, 0, 1, 0
                                                        ]);
    private const SKIN:ColorMatrixFilter = new ColorMatrixFilter([
                                                            0, 0, 0, 0, 0,
                                                            -0.43, -0.85, 1.28, 0, 198.4,
                                                            1.28, -1.07, -0.21, 0, 108.8,
                                                            0, 0, 0, 1, 0
                                                        ]);
    private const FONT_SIZE_LIST:Array = new Array(12, 18, 24, 30, 36, 48);
    
    private var _camera:Camera;
    private var _video:Video;
    private var _now:BitmapData;
    private var _prev:BitmapData;
    private var _rect:Rectangle;
    private var _pt:Point;
    private var _s:Sprite;                            //差分表示用Sprite
    private var _photos:Array;                        //撮影した画像を保持(BitmapData)
    private var _rects:Vector.<Rectangle>;
    private var _moveVols:Vector.<Number>;            //過去数回分の動いた量を保持
    private var _shootVol:Number;                    //動いた量を保持
    private var _balloonContainer:Sprite;            //吹き出し表示用
    
    private var _stayFlg:Boolean;                    //演出中はtrue
    private var _youkyuStep:Number;
    private var _youkyuFlg:Boolean;                    //要求可能になったらtrue
    private var _youkyuWords:Array;
    
    private var _homeWords:Array;
    private var _homeBmds:Array = new Array();        //必要なBitmapDataをプリレンダリングし格納
    
    public function Step2(homeWords:Array, youkyuWords:Array) {
        addEventListener(Event.ADDED, init);
        //
        _homeWords = homeWords;
        _youkyuWords = youkyuWords;
        //プリレンダリング
        for(var i:uint=0; i<_homeWords.length; i++){
            _homeBmds[i] = new Vector.<BitmapData>();    //フォントサイズ違いのBitmapDataを保持
            for(var j:uint=0; j<FONT_SIZE_LIST.length; j++){
                var tf:TextField = MyTF.createTF(_homeWords[i], 0xFFFFFF, FONT_SIZE_LIST[j], -1);
                _homeBmds[i][j] = createBalloonBmd(tf, MyColor.PINK);
            }
            }
    }
    
    private function init(e:Event):void {
        removeEventListener(Event.ADDED, init);
        _photos = new Array();
        _rects = new Vector.<Rectangle>();
        _moveVols = new Vector.<Number>(3);
        _shootVol = 0;
        _camera = Camera.getCamera();
        if (_camera == null) return;
        _camera.setMode(455, 455, 10, false);
        _video = new Video(_camera.width, _camera.height);
        _video.attachCamera(_camera);
        _video.scaleX = -1;
        _video.x = _camera.width;
        addChild(_video);
        _camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler );
    }
    
    private function activityHandler(e:ActivityEvent):void {
        _camera.removeEventListener(ActivityEvent.ACTIVITY, activityHandler );
        _video.x += Math.floor(stage.stageWidth/2 - width/2);
        _video.y += Math.floor(stage.stageHeight/2 - height/2);
        //
        _s = new Sprite();
        _now = new BitmapData(_camera.width, _camera.height, false);
        _prev = new BitmapData(_camera.width, _camera.height, false);
        _rect = new Rectangle(0, 0, _camera.width, _camera.height);
        _pt = new Point;
        //ふきだし表示用Spriteを生成
        _balloonContainer = new Sprite();
        _balloonContainer.x = Math.floor(stage.stageWidth/2 - width/2);
        _balloonContainer.y = Math.floor(stage.stageHeight/2 - height/2);
        addChild(_balloonContainer);
        //
        _youkyuStep = 0;
        _youkyuFlg = true;
        //
        var myTimer:Timer = new Timer(1000/10, 0);
            myTimer.addEventListener(TimerEvent.TIMER, update);
            myTimer.start();
        
    }
    
    private function nextYoukyou(e:TimerEvent):void {
        _youkyuFlg = true;
        _youkyuStep++;
        
    }
    private function cancelStay(e:TimerEvent):void {
        _stayFlg = false;
    }
    private function lastShootComplete(e:TimerEvent):void {
        dispatchEvent( new MyEvent(MyEvent.COMPLETE, _photos) );
    }

    private function update(e:TimerEvent):void {
        _s.graphics.clear();
        _now.draw(_video, new Matrix(-1,0,0,1,_camera.width));
        var copy:BitmapData = _now.clone();
        _now.draw(_prev, new Matrix(), new ColorTransform(), BlendMode.DIFFERENCE);
        _prev = copy.clone();
        copy.applyFilter(_now, _rect, _pt, SKIN);
        _now.applyFilter(_now, _rect, _pt, GRAY_SCALE);
        _now.threshold(_now, _rect, _pt, ">", 0xff111111, 0xffffffff);
        _now.threshold(copy, _rect, _pt, "!=", 0x008080, 0xff000000, 0x00c0c0);
        _now.applyFilter(_now, _rect, _pt, NOISE_REDUCTION);
        //
        _rects = new Vector.<Rectangle>();
        var bound:Rectangle = _now.getColorBoundsRect(0xffffff, 0xffffff);
        var line:BitmapData = new BitmapData(_rect.width, 1, false);
        var lineBound:Rectangle = new Rectangle(0, 0, _rect.width, 1);
        var nowMoveVol:Number = 0;
        while (!bound.isEmpty()) {
            lineBound.y = bound.y;
            line.copyPixels(_now, lineBound, _pt);
            bound = line.getColorBoundsRect(0xffffff, 0xffffff);
            _now.floodFill(bound.x, lineBound.y, 0xff00ff);
            var rect:Rectangle = _now.getColorBoundsRect(0xffffff, 0xff00ff);
            rect.inflate(4, 4);
            _now.fillRect(rect, 0x0000ff);
            _rects.push(rect);
            bound = _now.getColorBoundsRect(0xffffff, 0xffffff);
            nowMoveVol++;
        }
        
        if(!_stayFlg){
            //過去数回分に動いた量を算出
            _moveVols.shift();
            _moveVols.push(nowMoveVol);
            var recentVol:Number = 0;    //過去数回分の合計値
            for(var i:uint=0; i<_moveVols.length; i++){
                recentVol += _moveVols[i];
            }
            _shootVol += Math.min(nowMoveVol, 10);
            //一定量動いた後、動きが静まったタイミングで撮影
            if(_shootVol>120 && recentVol<20){
                shoot();    //撮影
                _shootVol = 70;
                _stayFlg = true;
                var sT:Timer;
                //要求がまだあるか判定
                if(_youkyuStep < _youkyuWords.length-1) {
                    sT = new Timer(1000, 1);
                    sT.addEventListener(TimerEvent.TIMER, cancelStay);
                    sT.start();
                }else{
                    _video.attachCamera(null);    //カメラを停止
                    removeChild(_video);
                    sT = new Timer(2000, 1);
                    sT.addEventListener(TimerEvent.TIMER, lastShootComplete);
                    sT.start();
                }
            }else if(_youkyuFlg){
                _youkyuFlg = false;
                _stayFlg = true;
                createYoukyu();    //要求する
                var kT:Timer = (_youkyuStep == _youkyuWords.length-1)? new Timer(3500, 1) : new Timer(2500, 1);
                kT.addEventListener(TimerEvent.TIMER, cancelStay);
                kT.start();
                //要求がまだあるか判定
                if(_youkyuStep < _youkyuWords.length-1) {
                    var  nT:Timer = new Timer(Math.random()*4000+8000, 1);
                    nT.addEventListener(TimerEvent.TIMER, nextYoukyou);
                    nT.start();
                }
            }else if(nowMoveVol > 10 && _rects.length > 0 && _balloonContainer.numChildren < 7 ){
                createHomeru();    //褒める
            }
        }
    }
    
    //褒める
    private function createHomeru():void {
        var l:Number = _rects.length;
        var myRect:Rectangle = _rects[ Math.floor(Math.random()*l) ];
        var myX:Number = myRect.x + myRect.width/2;
        var myY:Number = myRect.y + myRect.height/2;
        var size:Number = Math.min(72, Math.max(10, l/3));
        for(var i:uint=0; i<FONT_SIZE_LIST.length-1; i++){
            if(size < FONT_SIZE_LIST[i]) break;
        }
        var homeNum:Number = Math.floor(Math.random()*_homeWords.length);
        var bm:Bitmap = new Bitmap(_homeBmds[homeNum][i]/*, "never", true*/);
        var balloon:MyBalloon = new MyBalloon(bm);
        balloon.x = myX;
        balloon.y = myY;
        balloon.popUp();
        _balloonContainer.addChild(balloon);
    }
    
    //要求する
    private function createYoukyu():void {
        var tf:TextField = MyTF.createTF(_youkyuWords[_youkyuStep], MyColor.PINK, 24, -.5);
        var bm:Bitmap = new Bitmap( createBalloonBmd(tf, 0x000000) );
        var balloon:MyBalloon = new MyBalloon(bm);
        balloon.x = _video.width/2;
        balloon.y = _video.height/2;
        balloon.slowFade();
        _balloonContainer.addChild(balloon);
    }

    
    //吹き出しを生成
    private function createBalloonBmd(tf:TextField, sC:Number):BitmapData {
        var paddingW:Number = 18;
        var paddingH:Number = 10;
        var tempBmd:BitmapData = new BitmapData(tf.width, tf.height, true, 0x00000000);
        tempBmd.draw(tf);
        var bound:Rectangle = tempBmd.getColorBoundsRect(0xFFFFFFFF, 0x00000000, false);
        var scale:Number = 1;
        if(bound.width > 400){
            scale = 400 / bound.width;
            bound.x *= scale;
            bound.y *= scale;
            bound.width = Math.floor(bound.width*scale);
            bound.height = Math.floor(bound.height*scale);
        }
        //ザブトン生成
        var s:Sprite = new Sprite();
        s.graphics.beginFill(sC, 1);
        s.graphics.drawRect(0, 0, bound.width+paddingW, bound.height+paddingH);
        //
        var tfBmd:BitmapData = new BitmapData(bound.width+paddingW, bound.height+paddingH, true, 0x00000000);
        tfBmd.draw(s);
        tfBmd.draw(tempBmd, new Matrix(scale, 0, 0, scale, -bound.x+paddingW/2, -bound.y+paddingH/2),null, null, null, true);
        return tfBmd;
    }
    
    //写真撮影
    private function shoot():void {
        var bmd:BitmapData = new BitmapData(_camera.width, _camera.height, false);
        bmd.draw(_video, new Matrix(-1,0,0,1,_camera.width));
        var p:MyPhoto = new MyPhoto(bmd);
        addChild(p);
        
        //画像を縮小し格納
        var smallBmd:BitmapData = new BitmapData(120, 120, false);
        smallBmd.draw(bmd, new Matrix(120/bmd.width, 0, 0, 120/bmd.height, 0, 0), null, null, null, true);
        _photos.push(smallBmd);
        
    }
}





import flash.display.Shape;
//import flash.display.Sprite;
//import flash.display.Bitmap;
//import flash.display.BitmapData;
//import flash.display.Stage;
//import flash.events.Event;
//import flash.geom.Matrix;
//import org.libspark.betweenas3.BetweenAS3;
//import org.libspark.betweenas3.easing.*;
//import org.libspark.betweenas3.tweens.ITween;
//import org.libspark.betweenas3.events.TweenEvent;

class MyPhoto extends Sprite {
    private var _photoBmd:BitmapData;
    private var _myTween:ITween;
    
    public function MyPhoto(photoBmd:BitmapData) {
        _photoBmd = photoBmd;
        
        addEventListener(Event.ADDED, onAddedHandler);
    }
    
    public function init():void {
        var w:Number = _photoBmd.width;
        var h:Number = _photoBmd.height;
        //
        var frame:Shape = new Shape();
        frame.graphics.beginFill (0xFFFFFF, 1);
        frame.graphics.drawRect  (0, 0, w, h);
        addChild(frame);
        //
        var bmd:BitmapData = new BitmapData(w-20, h-20, false);
        bmd.draw(_photoBmd, new Matrix(1, 0, 0, 1, -10, -10));
        var bm:Bitmap = new Bitmap(bmd);
        bm.x = bm.y = 10;
        addChild(bm);
        //
        var pivot:Number = Math.random()*w;
        var shiftX:Number = -(pivot-w/2)*.1;
        shiftX = 0;
        var lr:Number;
        (pivot > w/2)? lr=1 : lr=-1;
        var rot:Number = Math.random()*60*lr;
        //
        x = Math.floor(stage.stageWidth/2 - w/2 + pivot);
        y = Math.floor(stage.stageHeight/2 - h/2);
        frame.x -= pivot;
        bm.x -= pivot;
        //
        var t:ITween =    BetweenAS3.parallel(
                            BetweenAS3.tween(bm, {transform: {colorTransform: {redOffset: 0, greenOffset: 0, blueOffset: 0}}},
                                             {transform: {colorTransform: {redOffset: 255, greenOffset: 255, blueOffset: 255}}},
                                             1, Sine.easeOut),
                            BetweenAS3.delay( BetweenAS3.tween(this, {x:x+shiftX, y:stage.stageHeight*2, rotation:rot }, null, 1, Quart.easeIn), .5)
                        );
        t.addEventListener(TweenEvent.COMPLETE, onComplete);
        t.play();
    }
     
    private function onComplete(e:TweenEvent):void {
        parent.removeChild(this);
    }
    
    private function onAddedHandler(e:Event):void {
        removeEventListener(Event.ADDED, onAddedHandler);
        init();
    }
}





//import flash.display.Bitmap;
//import flash.display.Sprite;
//import org.libspark.betweenas3.BetweenAS3;
//import org.libspark.betweenas3.easing.*;
//import org.libspark.betweenas3.tweens.ITween;
//import org.libspark.betweenas3.events.TweenEvent;

class MyBalloon extends Sprite {
    public function MyBalloon(bm:Bitmap) {
        addChild(bm);
        bm.x = -bm.width/2;
        bm.y = -bm.height/2;
        
    }
    
    public function popUp(delay:Number=1):void {
        var t:ITween =    BetweenAS3.serial(
                            BetweenAS3.tween(this, { y:y-5 }, { y:y+10 }, .2, Cubic.easeOut),
                            BetweenAS3.tween(this, { y:y }, null, .4, Cubic.easeInOut),
                            BetweenAS3.delay(BetweenAS3.tween(this, { alpha:0 }, null, .2, Sine.easeOut), delay)
                        );
        t.addEventListener(TweenEvent.COMPLETE, onComplete);
        t.play();
    }
    
    public function slowFade():void {
        var t:ITween =    BetweenAS3.serial(
                            BetweenAS3.tween(this, { alpha:1 }, { alpha:0 }, 1, Cubic.easeIn),
                            BetweenAS3.delay(BetweenAS3.tween(this, { alpha:0 }, null, 1.5, Sine.easeOut), 3)
                        );
        t.addEventListener(TweenEvent.COMPLETE, onComplete);
        t.play();
    }
    
    private function onComplete(e:TweenEvent):void {
        parent.removeChild(this);
    }
}





//import flash.display.Shape;
//import flash.display.Sprite;
//import flash.display.Bitmap;
//import flash.display.BitmapData;
//import flash.geom.Matrix;
//import flash.geom.Point;
//import flash.geom.ColorTransform;
//import flash.geom.Rectangle;
//import flash.text.TextField;
//import flash.events.Event;
import flash.events.MouseEvent;
//import org.libspark.betweenas3.BetweenAS3;
//import org.libspark.betweenas3.easing.*;

class Step3 extends Sprite {
    private const SIZE_W:Number = 120;
    private const SIZE_H:Number = 120;
    private const FONT_SIZE_LIST:Array = new Array(12, 24, 36, 48, 60, 72, 84, 96);
    private var _scaleRate:Number;
    private var _bmd:BitmapData;
    private var _pointList:Array;
    private var _textBmds:Array = new Array();
    private var _parallelNum:Number;        //同時処理数
    private var _photoBmds:Array;            //撮影した画像を保持(BitmapData)
    private var _nowPhotoNum:Number;        //現在の写真番号
    private var _typoContainer:Sprite;
    private var _typoWords:Array;
    
    public function Step3(typoWords:Array, photoBmds:Array) {
        addEventListener(Event.ADDED, init);
        _typoWords = typoWords;
        _photoBmds = photoBmds;
    }
    
    private function init(e:Event):void {
        removeEventListener(Event.ADDED, init);
        _nowPhotoNum = 0;
        _typoContainer = new Sprite();
        addChild(_typoContainer);
        //プリレンダリング
        for(var i:uint=0; i<_typoWords.length; i++){
            _textBmds[i] = new Vector.<BitmapData>();    //フォントサイズ違いのBitmapDataを保持
            for(var j:uint=0; j<FONT_SIZE_LIST.length; j++){
                var str:String = _typoWords[i].toUpperCase();
                var tf:TextField = MyTF.createTF(str, 0xFF1111, FONT_SIZE_LIST[j], -2);
                var tfBmd:BitmapData = new BitmapData(tf.width, tf.height, true, 0x00000000);
                tfBmd.draw(tf);
                var bound:Rectangle = tfBmd.getColorBoundsRect(0xFFFFFFFF, 0x00000000, false);
                //BitmapDataを配列に格納。変形させるので周りに1ピクセル余白をとる
                _textBmds[i][j] = new BitmapData(bound.width+2, bound.height+2, true, 0x00000000);
                _textBmds[i][j].draw(tf, new Matrix(1, 0, 0, 1, -bound.x+1, -bound.y+1));
            }
            }
        reset();
        stage.addEventListener(MouseEvent.CLICK, reset);
    }
    
    private function reset(e:MouseEvent=null):void {
        //_typoContainerの子オブジェクトをすべて削除
        while (_typoContainer.numChildren > 0) _typoContainer.removeChildAt(numChildren - 1);
        //
        var s:Number = Math.min(stage.stageWidth, stage.stageHeight);
        x = Math.floor(stage.stageWidth/2 - s/2);
        y = Math.floor(stage.stageHeight/2 - s/2);
        _parallelNum = 1;
        _scaleRate = stage.stageHeight/SIZE_H;
        _pointList = new Array();
        _bmd = binarization(pixelization(_photoBmds[_nowPhotoNum]));
        (_nowPhotoNum < _photoBmds.length-1)? _nowPhotoNum++ : _nowPhotoNum=0;
        addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
    }
    
    private function onEnterFrameHandler(e:Event):void {
        if(_pointList.length>0){
            for(var i:uint=0; i<Math.min(_parallelNum, _pointList.length); i++){
                var num:Number = Math.floor(Math.random()*_pointList.length);
                var p:Point = _pointList[num];
                _pointList.splice(num, 1);
                calculationRect(p);
            }
            if(_parallelNum<50) _parallelNum *= 1.01;
        }else{
            removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        }
    }
    
    private function calculationRect(p:Point):void {
        var myColor:Number = _bmd.getPixel(p.x, p.y);
        var sMin:Number = 3;
        var sMax:Number = 36;
        if(myColor != MyColor.DELETE){
            _bmd.setPixel(p.x, p.y, MyColor.DELETE);
            var max:Number = Math.floor(Math.random()*(sMax- sMin+1)) + sMin;
            var wordNum:Number = Math.floor(Math.random()*_textBmds.length);
            var ratio:Number = _textBmds[wordNum][FONT_SIZE_LIST.length-1].height / _textBmds[wordNum][FONT_SIZE_LIST.length-1].width;
            var myStatus:MyStatus = new MyStatus(wordNum, ratio, p.x, p.y, myColor, max);
            //拡大可能な限り拡大
            myStatus = spreadRect(myStatus);
            //レンダリング
            rendering(myStatus);
        }
    }
    
    //矩形を拡大
    private function spreadRect(rect:MyStatus, directionFlg:Object=null):MyStatus {
        if(directionFlg == null) directionFlg={t:false, r:false, b:false, l:false};
        var flg:Boolean;
        //左右または上下、どちらへ伸ばすか判定
        if( Math.floor(rect.myW*rect.ratio) <= rect.myH ){
            var h:uint;
            if(!directionFlg.r){
                //右に伸ばせるか判定
                for(h=0; h<rect.myH; h++){
                    if(rect.myColor != _bmd.getPixel(rect.myX+rect.myW, rect.myY+h) || rect.myX+rect.myW == SIZE_W || rect.myW > rect.max){
                        flg = true;
                        break;
                    }
                }
                //伸ばせる場合
                if(!flg){
                    for(h=0; h<rect.myH; h++){
                        _bmd.setPixel(rect.myX+rect.myW, rect.myY+h, MyColor.DELETE);
                    }
                    rect.myW += 1;
                    return arguments.callee(rect, directionFlg);
                }else{
                    directionFlg.r = true;
                    return arguments.callee(rect, directionFlg);
                }
            }else{
                //左に伸ばせるか判定
                for(h=0; h<rect.myH; h++){
                    if(rect.myColor != _bmd.getPixel(rect.myX-1, rect.myY+h) || rect.myX == 0 || rect.myW > rect.max){
                        flg = true;
                        break;
                    }
                }
                //伸ばせる場合
                if(!flg){
                    for(h=0; h<rect.myH; h++){
                        _bmd.setPixel(rect.myX-1, rect.myY+h, MyColor.DELETE);
                    }
                    rect.myX -= 1;
                    rect.myW += 1;
                    return arguments.callee(rect, directionFlg);
                }else{
                    directionFlg.l = true;
                }
            }
        }else{
            var w:uint;
            if(!directionFlg.b){
                //下に伸ばせるか判定
                for(w=0; w<rect.myW; w++){
                    if(rect.myColor != _bmd.getPixel(rect.myX+w, rect.myY+rect.myH) || rect.myY+rect.myH == SIZE_H || rect.myH > rect.max){
                        flg = true;
                        break;
                    }
                }
                //伸ばせる場合
                if(!flg){
                    for(w=0; w<rect.myW; w++){
                        _bmd.setPixel(rect.myX+w, rect.myY+rect.myH, MyColor.DELETE);
                    }
                    rect.myH += 1;
                    return arguments.callee(rect, directionFlg);
                }else{
                    directionFlg.b = true;
                    return arguments.callee(rect, directionFlg);
                }
            }else{
                //上に伸ばせるか判定
                for(w=0; w<rect.myW; w++){
                    if(rect.myColor != _bmd.getPixel(rect.myX+w, rect.myY-1) || rect.myY == 0 || rect.myH > rect.max){
                        flg = true;
                        break;
                    }
                }
                //伸ばせる場合
                if(!flg){
                    for(w=0; w<rect.myW; w++){
                        _bmd.setPixel(rect.myX+w, rect.myY-1, MyColor.DELETE);
                    }
                    rect.myY -= 1;
                    rect.myH += 1;
                    return arguments.callee(rect, directionFlg);
                }else{
                    directionFlg.t = true;
                }
            }
        }
        return rect;
    }
    
    //ピクセル化
    private function pixelization(bmd:BitmapData):BitmapData {
        var destBmd:BitmapData = new BitmapData(SIZE_W, SIZE_H, false);
        destBmd.draw(bmd, new Matrix(SIZE_W/bmd.width, 0, 0, SIZE_H/bmd.height, 0, 0), null, null, null, true);
        return destBmd;
    }
    
    //三値化
    private function binarization(bmd:BitmapData):BitmapData {
        var destBmd:BitmapData = bmd.clone();
        for (var myY:int=0; myY<SIZE_H; myY++){
            for (var myX:int=0; myX<SIZE_W; myX++){
                var myColor:Number = bmd.getPixel(myX, myY);
                if(myColor > 0xAAAAAA){
                    myColor = MyColor.PINK;
                }else if(myColor > 0x777777){
                    myColor = MyColor.PINK_HALF;
                }else{
                    myColor = MyColor.PINK_QUARTER;
                }
                destBmd.setPixel(myX, myY, myColor);
                _pointList.push( new Point(myX, myY) );
            }
        }
        return destBmd;
    }
    
    //レンダリング
    private function rendering(myStatus:MyStatus):void {
        var h:Number = myStatus.myH * _scaleRate * 2;
        var sizeNum:Number = FONT_SIZE_LIST[FONT_SIZE_LIST.length-1];
        for(var i:uint=0; i<FONT_SIZE_LIST.length-1; i++){
            if(h < FONT_SIZE_LIST[i]) break;
        }
        var bm:Bitmap = new Bitmap(_textBmds[myStatus.wordNum][i], "never", true);
        bm.x = myStatus.myX * _scaleRate;
        bm.y = myStatus.myY * _scaleRate;
        bm.width = myStatus.myW * _scaleRate;
        bm.height = myStatus.myH * _scaleRate;
        _typoContainer.addChild(bm);
        var c:Number = myStatus.myColor;
        var r:Number = ( c & 0xff0000 ) >> 16;
        var g:Number = ( c & 0xff00 ) >> 8;
        var b:Number = ( c & 0xff );
        var ctf : ColorTransform = new ColorTransform(0, 0, 0, 0, r, g, b,0);
        bm.transform.colorTransform = ctf;
        BetweenAS3.tween(bm, { alpha:1 }, { alpha:0 }, 1, Sine.easeOut).play();
    }
}





class MyStatus {
    public var wordNum:Number;
    public var ratio:Number;    //縦横比
    public var myX:Number;
    public var myY:Number;
    public var myColor:Number;
    public var max:Number;
    public var myW:Number = 1;
    public var myH:Number = 1;
    
    public function MyStatus(mWordNum:Number, mRatio:Number, mX:Number, mY:Number, mColor:Number, mMax:Number) {
        wordNum = mWordNum;
        ratio = mRatio
        myX = mX;
        myY = mY;
        myColor = mColor;
        max = mMax;
    }
}
    
    
    
    
    
//import flash.display.Sprite;
//import flash.text.TextField;
//import flash.events.Event;
//import flash.events.MouseEvent;
//import flash.events.EventDispatcher;
//import org.libspark.betweenas3.BetweenAS3;
//import org.libspark.betweenas3.easing.*;
//import org.libspark.betweenas3.tweens.ITween;
//import org.libspark.betweenas3.events.TweenEvent;

class Intro extends Sprite {
    private var _num:Number;
    private var _titleStr:String;
    private var _leadStr:String;
    private var _fadeFlg:Boolean;
    
    public function Intro(num:Number, titleStr:String, leadStr:String, fadeFlg:Boolean=true) {
        _num = num;
        _titleStr = titleStr;
        _leadStr = leadStr;
        _fadeFlg = fadeFlg;
        addEventListener(Event.ADDED, init);
    }
    
    private function init(e:Event):void {
        removeEventListener(Event.ADDED, init);
        //
        var w:Number = stage.stageWidth;
        var h:Number = stage.stageHeight;
        graphics.beginFill (MyColor.PINK, 1);
        graphics.drawRect  (0, 0, w, h);
        //
        var s:Sprite = new Sprite();
        addChild(s);
        //
        var numText:MyText = new MyText( MyTF.createTF("Step"+_num, 0x000000, 24, -1) );
        numText.x = -numText.w/2;
        s.addChild(numText);
        //
        var titleText:MyText = new MyText( MyTF.createTF(_titleStr, 0x000000, 72, 0) );
        titleText.x = -titleText.w/2;
        titleText.y = numText.h+20;
        s.addChild(titleText);
        //
        var leadText:MyText = new MyText( MyTF.createTF(_leadStr, 0x000000, 16, 0, 400) );
        leadText.x = -leadText.w/2;
        leadText.y = titleText.y+titleText.h+60;
        s.addChild(leadText);
        //
        s.x = w/2;
        s.y = h/2-s.height/2;
        //
        if(_fadeFlg){
            var cir:Sprite = createCircle(w/2, h/2, 1.5*Math.max(w, h)/2);
            addChild(cir);
            BetweenAS3.tween(cir, { width:0, height:0 }, null, 1, Cubic.easeOut).play();
        }
        buttonMode = true;
        addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
    }
    
    private function clickHandler(e:MouseEvent):void {
        buttonMode = false;
        removeEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
        var w:Number = stage.stageWidth;
        var h:Number = stage.stageHeight;
        var cir:Sprite = createCircle(w/2, h/2, 1);
        addChild(cir);
        var size:Number = 1.5*Math.max(w, h);
        var t:ITween = BetweenAS3.tween(cir, { width:size, height:size }, null, 1, Cubic.easeOut);
        t.addEventListener(TweenEvent.COMPLETE, function(e:TweenEvent):void {
            dispatchEvent( new Event(Event.COMPLETE) );
        });
        t.play();
    }
    
    private function createCircle(myX:Number, myY:Number, r:Number):Sprite {
        var cir:Sprite = new Sprite;
        cir.graphics.beginFill(0x000000, 1);
        cir.graphics.drawCircle(0, 0, r);
        cir.x = myX;
        cir.y = myY;
        return cir;
    }
}
    

    
        
    
//import flash.display.Sprite;
//import flash.text.TextField;
//import flash.events.Event;
//import flash.events.MouseEvent;
//import flash.events.EventDispatcher;
import flash.events.DataEvent;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;

class MyForm extends Sprite {
    private const ERROR_STR:String = "入力してください。";
    public static const COMPLETE:String = "complete";
    private var _dtf:TextField;
    private var _submit:Sprite;
    private var _num:Number;
    private var _question:String;
    
    public function MyForm(num:Number, question:String) {
        _num = num;
        _question = question;
        addEventListener(Event.ADDED, init);
    }
    
    private function init(e:Event):void {
        removeEventListener(Event.ADDED, init);
        //
        var numText:MyText = new MyText( MyTF.createTF("Question"+_num, MyColor.PINK, 36, -1) );
        numText.x = -numText.w/2;
        addChild(numText);
        //
        var questionText:MyText = new MyText( MyTF.createTF(_question, MyColor.PINK, 18, 0, 400) );
        questionText.x = -questionText.w/2;
        questionText.y = numText.h+20;
        addChild(questionText);
        //
        _dtf = MyTF.createDTF(MyColor.PINK);
        addChild(_dtf);
        _dtf.x = -(_dtf.width+80)/2;
        _dtf.y = questionText.y+questionText.h+60;
        stage.focus = _dtf;
        //
        _submit = new Sprite();
        _submit.graphics.beginFill(MyColor.PINK, 1);
        _submit.graphics.drawRect(0, 0 , 80 , 19);
        _submit.x = _dtf.x+_dtf.width+2;
        _submit.y = _dtf.y;
        var t:TextField = MyTF.createTF("決定", 0xFFFFFF, 14);
        var myText:MyText = new MyText(t);
        myText.x = _submit.width/2 - myText.w/2;
        myText.y = _submit.height/2 - myText.h/2;
        _submit.addChild(myText);
        addChild(_submit);
        //
        _submit.buttonMode = true;
        _submit.mouseChildren = false;
        _submit.addEventListener(MouseEvent.ROLL_OVER, overHandler);
        _submit.addEventListener(MouseEvent.ROLL_OUT, outHandler);
        _submit.addEventListener(MouseEvent.CLICK, clickHandler);
        _dtf.addEventListener(FocusEvent.FOCUS_IN, focusInHandler);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownHandler);
    }
    
    private function overHandler(e:MouseEvent):void {
        e.target.alpha = .6;
    }
    private function outHandler(e:MouseEvent):void {
        e.target.alpha = 1;
    }
    private function clickHandler(e:MouseEvent):void {
        if(_dtf.text=="" || _dtf.text==ERROR_STR){
            _dtf.text = ERROR_STR;
        }else{
            _submit.removeEventListener(MouseEvent.ROLL_OVER, overHandler);
            _submit.removeEventListener(MouseEvent.ROLL_OUT, outHandler);
            _submit.removeEventListener(MouseEvent.CLICK, clickHandler);
            _dtf.removeEventListener(FocusEvent.FOCUS_IN, focusInHandler);
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDownHandler);
            dispatchEvent(new DataEvent(MyForm.COMPLETE, false, false, _dtf.text));
        }
    }
    private function focusInHandler(e:FocusEvent):void {
        if(_dtf.text==ERROR_STR) _dtf.text = "";
    }
    private function onKeyDownHandler(e:KeyboardEvent):void {
        if(_dtf.text==ERROR_STR) _dtf.text = "";
        if(e.keyCode == 13) clickHandler(null);
    }
}





//import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldType;
class MyTF {
    public static function createTF(str:String, myColor:Number, size:Number=24, ls:Number=0, w:Number=0):TextField {
        var fmt:TextFormat = new TextFormat();
        fmt.font = "_明朝";
        fmt.color = myColor;
        fmt.size = size;
        fmt.bold = true;
        fmt.letterSpacing = ls;
        fmt.leading = 4;
        fmt.rightMargin = 1;
        var tf:TextField = new TextField();
        //tf.setTextFormat(fmt);
        tf.defaultTextFormat = fmt;
        //tf.text = str.toUpperCase();
        tf.text = str;
        tf.selectable = false;
        
        if(w == 0){
            tf.wordWrap = false;
            tf.autoSize = "left";
        }else{
            tf.width = w;
            tf.multiline = true;
            tf.wordWrap = true;
            tf.autoSize = "left";
        }
        return tf;
    }
    
    public static function createDTF(myColor:Number, size:Number=14):TextField {
        var fmt:TextFormat = new TextFormat();
        fmt.font = "_明朝";
        fmt.color = myColor;
        fmt.size = size;
        var tf:TextField = new TextField();
        tf.defaultTextFormat = fmt;
        tf.type = TextFieldType.INPUT; 
        tf.width = 140;
        tf.height = 18;
        tf.border = true;
        tf.borderColor = myColor;
        return tf;
    }
}





//import flash.text.TextField;
//import flash.text.TextFormat;
//import flash.display.BitmapData;
//import flash.geom.Rectangle;
//import flash.display.Sprite;
//import flash.display.Bitmap;

class MyText extends Sprite {
    private var _tfBmd:BitmapData;
    private var _bound:Rectangle;
    
    public function get w():Number {
        return _bound.width;
    }
    public function get h():Number {
        return _bound.height;
    }
    
    public function MyText(tf:TextField) {
        _tfBmd = new BitmapData(tf.width, tf.height, true, 0x00000000);
        _tfBmd.draw(tf);
        _bound = _tfBmd.getColorBoundsRect(0xFFFFFFFF, 0x00000000, false);
        var tfBitmap:Bitmap = new Bitmap(_tfBmd);
        tfBitmap.x = -_bound.x;
        tfBitmap.y = -_bound.y;
        addChild(tfBitmap);
    }
}
    



    
//import flash.events.Event;
class MyEvent extends Event {
    public static const COMPLETE:String = "complete";
    public var v:Array;
      
    public function MyEvent(type:String, v:Array):void {  
        super(type);
        this.v = v;
    }
    
    public override function clone():Event {
        return new MyEvent(type, v);
    }
      
    public override function toString():String {
        return formatToString("MyEvent", "type", "bubbles", "cancelable", "eventPhase", "v");
    }  
}





class MyColor {
    public static const PINK:Number = 0xFF3366;
    public static const PINK_HALF:Number = 0x8C1C38;
    public static const PINK_QUARTER:Number = 0x330A14;
    public static const DELETE:Number = 0x00FF00;
}