Beautifl - Flash Gallery

Thumbnail : up to you
up to you
buccchi 2010-01-05 MIT License

Flash Player is required to play. Please revisit at the desktop browser.

// 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, "質問", "まずは5つの質問にお答えください。\n   クリックでスタート。", false);
			intro1.addEventListener(Event.COMPLETE, intro1Complete);
			addChild(intro1);
        }
        
        private function intro1Complete(e:Event):void {
			var questions:Array = ["あなたは男性、それとも女性?",
									"自分の体、自信があるのはどのパーツ?",
									"異性に言われて興奮する言葉は?",
						 			"セクシーだと思う服装は?",
									"野球拳、どこまで脱げる?"];
			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;
}