// forked from checkmate's Progression4 Amateur /* * 顔時計 * 時:顔色 * 分:顔の角度 * 秒:髪の角度 * * 1分に1度、ハンサム顔になります。 */ package { import flash.display.*; import flash.events.*; import jp.progression.casts.*; import jp.progression.commands.*; import jp.progression.commands.lists.*; import jp.progression.commands.net.*; import jp.progression.config.*; import jp.progression.data.*; import jp.progression.events.*; import jp.progression.scenes.*; import jp.progression.*; import flash.display.BitmapData; import flash.display.Bitmap; import flash.geom.Matrix; import flash.geom.Rectangle; import flash.utils.Timer; import flash.events.TimerEvent; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.easing.*; //import net.hires.debug.Stats; [SWF( width=465, height=465, backgroundColor=0xFFFFFF, frameRate=30 )] public class Amateur extends Sprite { private const WIDTH:Number = 465; private const HEIGHT:Number = 465; public var manager:Progression, self:Amateur; // Graphics public var face:MovieClip; public var hair:MovieClip; public var eyeBrowLeft:MovieClip, eyeBrowRight:MovieClip; public var eyeLeft:MovieClip, eyeRight:MovieClip; public var nose:MovieClip; public var mouth:MovieClip; private var _status:Array; private var _head:Sprite; private var _face:FaceSprite; private var _hairL:Sprite; private var _hairR:Sprite; private var _hairStatus:Array; private var _faceChilds:Array; private var _nowSeconds:Number; // Do Something public function atReady():void { //メモリ使用量表示 //addChild(new Stats()); //文字盤生成 var disk:ClockDisk = new ClockDisk(); disk.x = WIDTH/2; disk.y = HEIGHT/2; addChild( disk ); //顔生成 _face = new FaceSprite( face ); //すべてのパーツを原点移動 var difX:Number = _face.x; var difY:Number = _face.y; var parts:Array = [_face, hair, mouth, nose, eyeLeft, eyeRight, eyeBrowLeft, eyeBrowRight]; for each(var c:DisplayObject in parts) { c.x -= difX; c.y -= difY; } //hairの移動情報 var hX:Number = hair.x; var hY:Number = hair.y; _hairStatus = [{angle:0, x:hX, y:hY, sX:1, sY:1, d:"LR"}, {angle:49, x:hX+5, y:hY, sX:1, sY:1, d:"LR"}, {angle:50, x:hX+5, y:hY, sX:1, sY:1, d:"R"}, {angle:144, x:hX+10, y:hY, sX:1, sY:1, d:"R"}, {angle:145, x:hX+10, y:hY, sX:1, sY:1, d:"FACE"}, {angle:164, x:hX+5, y:hY, sX:1, sY:1, d:"FACE"}, //ヒゲ {angle:165, x:hX+5, y:hY+170, sX:.5, sY:.3, d:"LR"}, {angle:180, x:hX, y:hY+175, sX:.5, sY:.3, d:"LR"}, {angle:200, x:hX-5, y:hY+170, sX:.5, sY:.3, d:"LR"}, // {angle:201, x:hX-15, y:hY, sX:1, sY:1, d:"FACE"}, {angle:250, x:hX-15, y:hY, sX:1, sY:1, d:"FACE"}, {angle:251, x:hX-15, y:hY, sX:1, sY:1, d:"L"}, {angle:320, x:hX-5, y:hY, sX:1, sY:1, d:"L"}, {angle:321, x:hX-5, y:hY, sX:1, sY:1, d:"LR"}, {angle:360, x:hX, y:hY, sX:1, sY:1, d:"LR"}]; //heirを左右に分割 //中心点 var pivotX:Number = 132; var pivotY:Number = 119; //右髪を生成 _hairR = new Sprite(); var bmpDataR:BitmapData = new BitmapData(105+1, 238, true, 0x0); bmpDataR.draw(hair, new Matrix(1, 0, 0, 1, pivotX, pivotY), null, null, null, false); var bmpR:Bitmap = new Bitmap(bmpDataR); bmpR.smoothing = true; bmpR.x = -pivotX; bmpR.y = -pivotY; _hairR.addChild(bmpR); //左髪を生成 _hairL = new Sprite(); var bmpDataL:BitmapData = new BitmapData(159, 238, true, 0x0); bmpDataL.draw(hair, new Matrix(1, 0, 0, 1, pivotX-105, pivotY), null, null, null, false); var bmpL:Bitmap = new Bitmap(bmpDataL); bmpL.smoothing = true; bmpL.x = -pivotX+105; bmpL.y = -pivotY; _hairL.addChild(bmpL); _hairL.x = _hairR.x = hair.x; _hairL.y = _hairR.y = hair.y; _head = new Sprite(); _head.x = WIDTH/2; _head.y = HEIGHT/2; addChild( _head ); _head.addChild( _face ); _face.addChild( mouth ); _face.addChild( nose ); _face.addChild( eyeLeft ); _face.addChild( eyeRight ); _face.addChild( eyeBrowLeft ); _face.addChild( eyeBrowRight ); _head.addChild( _hairR ); _head.addChild( _hairL ); //初期状態を保持 _faceChilds = [mouth, nose, eyeLeft, eyeRight, eyeBrowLeft, eyeBrowRight]; _status = []; for each(var child:DisplayObject in _faceChilds) { child.x -= _face.x; child.y -= _face.y; _status.push( { x:child.x, y:child.y, scaleX:child.scaleX, scaleY:child.scaleY, rotation:child.rotation } ); } addEventListener(Event.ENTER_FRAME, onEnterframe); } private function onEnterframe(e:Event):void { var nowDate:Date = new Date(); if ( _nowSeconds != nowDate.seconds ) { _nowSeconds = nowDate.seconds; var h:Number = nowDate.hours; var m:Number = nowDate.minutes; var s:Number = nowDate.seconds; var hAngle:Number = ((h % 12) * 30) + (m / 2) + (s/120); var mAngle:Number = (m * 6) + (s / 10); var sAngle:Number = s * 6; updateClock(hAngle, mAngle, sAngle); //髪と顔の角度が同じ(近い)ときはハンサム顔に if(Math.abs(mAngle+1-sAngle)<3){ changeHandsomeFace(); }else{ changeFace(); } } } private function updateClock(hA:Number=0, mA:Number=0, sA:Number=0):void { _face.changeColor( hA ); _head.rotation = mA; var hairAngle:Number = sA-Math.floor(mA); if(hairAngle<0){ hairAngle += 360 }; var i:uint = getHairStatusIndex(hairAngle); var range:Number = _hairStatus[i+1].angle - _hairStatus[i].angle; var step:Number = hairAngle - _hairStatus[i].angle; var rate:Number = range/step; var targetX:Number = _hairStatus[i].x + (_hairStatus[i+1].x - _hairStatus[i].x) / rate; var targetY:Number = _hairStatus[i].y + (_hairStatus[i+1].y - _hairStatus[i].y) / rate; var targetScaleX:Number = _hairStatus[i].sX + (_hairStatus[i+1].sX - _hairStatus[i].sX) / rate; var targetScaleY:Number = _hairStatus[i].sY + (_hairStatus[i+1].sY - _hairStatus[i].sY) / rate; _hairL.rotation = _hairR.rotation = hairAngle; _hairL.x = _hairR.x = targetX; _hairL.y = _hairR.y = targetY; _hairL.scaleX = _hairR.scaleX = targetScaleX; _hairL.scaleY = _hairR.scaleY = targetScaleY; //深度変更 switch(_hairStatus[i].d){ case "L": _head.setChildIndex(_face, 0); _head.setChildIndex(_hairR, 0); break; case "R": _head.setChildIndex(_face, 0); _head.setChildIndex(_hairL, 0); break; case "LR": _head.setChildIndex(_face, 0); break; default: _head.setChildIndex(_hairL, 0); _head.setChildIndex(_hairR, 0); } } private function getHairStatusIndex(hairAngle:Number):uint { for(var i:uint=0; i<_hairStatus.length-1; i++){ if(hairAngle >= _hairStatus[i].angle && hairAngle < _hairStatus[i+1].angle){ return i; } } return null; } //表情を変える private function changeFace():void { var baseY:Number = ( Math.random() - .8 ) * 30; for ( var i:uint=0; i<_faceChilds.length; i++ ) { var child:DisplayObject = _faceChilds[i]; var status:Object = _status[i]; BetweenAS3.tween(child, { x:status.x + ( Math.random() - 0.5 ) * 15, y:status.y + ( Math.random() - 0.5 ) * 15 + baseY, scaleX:status.scaleX + ( Math.random() - 0.6 ) / 2, scaleY:status.scaleY + ( Math.random() - 0.5 ) / 3, rotation:status.rotation + ( Math.random() - 0.5 ) * 40 }, null, .3, Cubic.easeOut).play(); } } private function changeHandsomeFace():void { for ( var i:uint=0; i<_faceChilds.length; i++ ) { var child:DisplayObject = _faceChilds[i]; var status:Object = _status[i]; var difY:Number = 0; var difRotation:Number = 0; switch(child){ case eyeBrowLeft: difY = 10; difRotation = -10; break; case eyeBrowRight: difY = 10; difRotation = 10; break; } BetweenAS3.tween(child, { x:status.x, y:status.y+difY, scaleX:status.scaleX, scaleY:status.scaleY, rotation:status.rotation+difRotation }, null, .3, Cubic.easeOut).play(); } } /*private function _click( e:MouseEvent ):void { for ( var i:int = 0, l:int = numChildren; i < l; i++ ) { var child:DisplayObject = getChildAt( i ); var status:Object = _status[i]; child.x = status.x + ( Math.random() - 0.5 ) * 10; child.y = status.y + ( Math.random() - 0.5 ) * 10; child.scaleX = status.scaleX + ( Math.random() - 0.5 ) / 2; child.scaleY = status.scaleY + ( Math.random() - 0.5 ) / 2; child.rotation = status.rotation + ( Math.random() - 0.5 ) * 10; } }*/ public function Amateur() { CheckmateBuilder.initialize( this ); } } } import flash.display.DisplayObject; import flash.display.Sprite; import flash.display.MovieClip; import flash.display.BitmapData; import flash.display.Bitmap; import flash.display.BitmapDataChannel; import flash.geom.Rectangle; import flash.geom.Point; import flash.geom.Matrix; import flash.geom.ColorTransform; import frocessing.color.FColor; import frocessing.color.ColorHSV; class FaceSprite extends Sprite { private var _c:ColorHSV; private var _hada:Bitmap; public function FaceSprite(ori:MovieClip) { _c = new ColorHSV(); x = ori.x; y = ori.y; var oriBmd:BitmapData = new BitmapData(ori.width, ori.height, true, 0x00000000); oriBmd.draw(ori, new Matrix(1, 0, 0, 1, ori.width/2, ori.height/2)); //輪郭 var rinkakuBmd:BitmapData = new BitmapData(ori.width, ori.height, true, 0x00000000); rinkakuBmd.copyChannel(oriBmd, new Rectangle(0, 0, ori.width, ori.height), new Point(), BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA); var rinkaku:Bitmap = new Bitmap(rinkakuBmd); //肌色 var hadaBmd:BitmapData = new BitmapData(ori.width, ori.height, true, 0xFFFFFF00); hadaBmd.copyChannel(oriBmd, new Rectangle(0, 0, ori.width, ori.height), new Point(), BitmapDataChannel.RED, BitmapDataChannel.ALPHA); _hada = new Bitmap(hadaBmd); //ハイライト var tekariBmd:BitmapData = new BitmapData(ori.width, ori.height, true, 0xFFFFFFFF); tekariBmd.copyChannel(oriBmd, new Rectangle(0, 0, ori.width, ori.height), new Point(), BitmapDataChannel.BLUE, BitmapDataChannel.ALPHA); var tekari:Bitmap = new Bitmap(tekariBmd); addChild( rinkaku ); addChild( _hada ); addChild( tekari ); for ( var i:int = 0; i<numChildren; i++ ) { var c:DisplayObject = getChildAt(i); c.x -= ori.width/2; c.y -= ori.height/2; Bitmap(c).smoothing = true; } } //顔色を変更 public function changeColor(h:Number):void { var rgb:Object = FColor.HSVtoRGB(h, .8, 1); var ct:ColorTransform = _hada.transform.colorTransform; ct.color = (rgb.r << 16) | (rgb.g << 8) | (rgb.b); _hada.transform.colorTransform = ct; } } class ClockDisk extends Sprite { public function ClockDisk() { var h:Number = 190; //半径 for(var i:uint=0; i<60; i++){ var angle:Number = i*6; var radian:Number = angle*Math.PI/180; var rgb:Object = FColor.HSVtoRGB(angle+90, .8, 1); var color:Number = (rgb.r << 16) | (rgb.g << 8) | (rgb.b); var l:Number; //線の長さ (angle%30 == 0) ? l=12 : l=4; graphics.lineStyle(0, color); graphics.moveTo(Math.cos(radian)*(h-l), Math.sin(radian)*(h-l)); graphics.lineTo(Math.cos(radian)*h, Math.sin(radian)*h); } } } import flash.display.*; import flash.events.*; import flash.net.URLRequest; import flash.system.ApplicationDomain; import jp.progression.casts.*; import jp.progression.commands.*; import jp.progression.commands.lists.*; import jp.progression.commands.net.*; import jp.progression.config.*; import jp.progression.data.*; import jp.progression.events.*; import jp.progression.scenes.*; import jp.progression.*; class CheckmateBuilder extends EventDispatcher { public static var GRAPHICS_URL:String = "http://swf.wonderfl.net/static/assets/checkmate04/AmateurAssets.swf"; private static var _target:Amateur; private static var _manager:Progression; public static function initialize( target:Amateur ):void { if ( _target ) { return; } _target = target; _target.self = target; Progression.initialize( new BasicAppConfig() ); _manager = new Progression( "index", _target.stage ); _manager.root.addEventListener( SceneEvent.SCENE_LOAD, _sceneLoad ); _manager.root.addEventListener( SceneEvent.SCENE_INIT_COMPLETE, _sceneInitComplete ); _manager.goto( _manager.root.sceneId ); } private static function _sceneLoad( e:SceneEvent ):void { _manager.root.addCommand( new LoadSWF( new URLRequest( GRAPHICS_URL ) ), function():void { var loader:Loader = Loader( this.latestData ); var domain:ApplicationDomain = loader.contentLoaderInfo.applicationDomain; _target.face = new ( domain.getDefinition( "Face" ) as Class ); _target.face.x = 234; _target.face.y = 242; _target.hair = new ( domain.getDefinition( "Hair" ) as Class ); _target.hair.x = 233; _target.hair.y = 194; _target.eyeBrowRight = new ( domain.getDefinition( "EyeBrowRight" ) as Class ); _target.eyeBrowRight.x = 190; _target.eyeBrowRight.y = 218; _target.eyeBrowLeft = new ( domain.getDefinition( "EyeBrowLeft" ) as Class ); _target.eyeBrowLeft.x = 270; _target.eyeBrowLeft.y = 218; _target.eyeRight = new ( domain.getDefinition( "EyeRight" ) as Class ); _target.eyeRight.x = 190; _target.eyeRight.y = 248; _target.eyeLeft = new ( domain.getDefinition( "EyeLeft" ) as Class ); _target.eyeLeft.x = 272; _target.eyeLeft.y = 243; _target.nose = new ( domain.getDefinition( "Nose" ) as Class ); _target.nose.x = 236; _target.nose.y = 275; _target.mouth = new ( domain.getDefinition( "Mouth" ) as Class ); _target.mouth.x = 242; _target.mouth.y = 322; } ); } private static function _sceneInitComplete( e:SceneEvent ):void { _target.atReady(); } } niumClock