// forked from mex's 【AS100本ノック】12回目:時計 /** * AS100本ノック * 12回目のお題は「時計」 * あなたなりの「時計」を表現してください。 **/ package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.filters.BlurFilter; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.easing.Quint; import org.libspark.betweenas3.events.TweenEvent; import org.libspark.betweenas3.tweens.IObjectTween; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.special.CompositeMaterial; import org.papervision3d.materials.special.Letter3DMaterial; import org.papervision3d.materials.special.ParticleMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.objects.special.ParticleField; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.typography.fonts.HelveticaBold; import org.papervision3d.typography.Text3D; import org.papervision3d.view.layer.ViewportLayer; import org.papervision3d.view.Viewport3D; public class Watch extends Sprite { private const BACKGROUND_COLOR:uint = 0xffffff, CAMERA_POSITION_Z:uint = 350, TWEEN_TIME:Number = 0.5, VIEW_PORT_NUMBER:uint = 6, WORD_BASE_Z:uint = 350, WORD_COLOR:uint = 0x0; private var _cameraVector:Vector.<Camera3D> = new Vector.<Camera3D>(), _isAnimationVector:Vector.<Boolean> = new Vector.<Boolean>(), _oldTimeVector:Vector.<uint> = new Vector.<uint>(), _particles:ParticleField, _scene:Scene3D, _stageHeight:Number, _stageWidth:Number, _viewportVector:Vector.<Viewport3D> = new Vector.<Viewport3D>(), _viewportLayerArray:Array = [], _wordVector:Vector.<Text3D> = new Vector.<Text3D>(), _wordZArray:Array = []; public function Watch():void { if ( stage ) init(); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( e:Event = null ):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.BEST; _stageWidth = stage.stageWidth; _stageHeight = stage.stageHeight; initData(); addScene(); addparticles(); addViewPort(); addCamera(); addWord(); Rendering(); } private function initData():void { var i:uint , valueZ:int; for ( i = 0; i < VIEW_PORT_NUMBER; i++ ) { _isAnimationVector[i] = false; _oldTimeVector[i] = 10; _viewportLayerArray[i] = new Array(); } valueZ = -( 10 * WORD_BASE_Z ) >> 1; for ( i = 0; i < 10; i++ ) { _wordZArray.push( valueZ ); valueZ += WORD_BASE_Z; } shuffleArray( _wordZArray ); } private function addScene():void { _scene = new Scene3D(); } private function addparticles():void { _scene.addChild( _particles = new ParticleField( new ParticleMaterial( WORD_COLOR , 1 , 1 , 1 ) , 600 , 10 , 3150 , 3150 ) ); } private function addViewPort():void { var i:uint , vp:Viewport3D , w:Number; w = _stageWidth / VIEW_PORT_NUMBER; for ( i = 0; i < VIEW_PORT_NUMBER; i++ ) { addChild( vp = new Viewport3D( w , _stageHeight , false ) ); vp.opaqueBackground = BACKGROUND_COLOR; vp.x = i * w; _viewportVector.push( vp ); } } private function addCamera():void { var i:uint , camera:Camera3D; for ( i = 0; i < VIEW_PORT_NUMBER; i++ ) { camera = new Camera3D(); camera.name = i.toString(); _cameraVector.push( camera ); } } private function addWord():void { var fontMaterial:Letter3DMaterial , i:uint , font:HelveticaBold , word:Text3D; font = new HelveticaBold(); fontMaterial = new Letter3DMaterial( WORD_COLOR ); for ( i = 0; i < 10; i++ ) { _scene.addChild( word = new Text3D( i.toString() , font , fontMaterial ) ); word.x = Math.random() * 1000; word.y = Math.random() * 1000 + 40; word.z = _wordZArray[i]; _wordVector.push( word ); makeViewportLayer( word ); } } private function makeViewportLayer( word:Text3D ):void { var i:uint; for ( i = 0; i < VIEW_PORT_NUMBER; i++ ) _viewportLayerArray[i].push( Viewport3D( _viewportVector[i] ).getChildLayer( word ) ); } private function Rendering():void { var i:uint, renderer:BasicRenderEngine; renderer = new BasicRenderEngine(); addEventListener( Event.ENTER_FRAME , function():void { for ( i = 0; i < VIEW_PORT_NUMBER; i++ ) { controlDepthOfField( i ); controlCamera( i , getTime() ); controlParticles(); renderer.renderScene( _scene , _cameraVector[i] , _viewportVector[i] ); } } ); } private function controlDepthOfField( num:uint ):void { var i:uint , len:uint, distance:Number , blurValue:Number; len = _wordVector.length; for ( i = 0; i < len; i++ ) { distance = getDistanceFromCamera( Camera3D( _cameraVector[num] ) , Text3D( _wordVector[i] ) ) - CAMERA_POSITION_Z; blurValue = Math.min( 8 , distance * .012 << 1 ); ViewportLayer( _viewportLayerArray[num][i] ).filters = [ new BlurFilter( blurValue , blurValue ) ]; } } private function getDistanceFromCamera( camera:Camera3D , word:Text3D ):Number { var vecX:Number , vecY:Number , vecZ:Number; vecX = word.sceneX - camera.x; vecY = word.sceneY - camera.y; vecZ = word.sceneZ - camera.z; return Math.sqrt( ( vecX * vecX ) + ( vecY * vecY ) + ( vecZ * vecZ ) ); } private function controlCamera( num:uint, timeVector:Vector.<uint> ):void { var word:Text3D , time:uint; time = timeVector[num]; if ( !_isAnimationVector[num] && _oldTimeVector[num] != time ) { word = _wordVector[ time ]; cameraTween( Camera3D( _cameraVector[num] ) , { x:word.x , y:word.y, z:word.z - CAMERA_POSITION_Z, time:TWEEN_TIME } ); _isAnimationVector[num] = true; _oldTimeVector[num] = time; } } private function getTime():Vector.<uint> { var date:Date , v:Vector.<uint> , hh:uint , mm:uint , ss:uint; date = new Date(); hh = date.getHours(); mm = date.getMinutes(); ss = date.getSeconds(); v = Vector.<uint>( [int( hh / 10 ), hh % 10, int( mm / 10 ), mm % 10, int( ss / 10 ), ss % 10] ); return v; } private function controlParticles():void { var angle:Number; angle = _particles.rotationY; angle += 0.07; angle = ( angle % 360 + 360 ) % 360; _particles.rotationX = _particles.rotationY = _particles.rotationZ = angle; } private function cameraTween( camera:Camera3D , o:Object ):void { var io:IObjectTween; io = BetweenAS3.tween( camera , { x:o.x , y:o.y , z:o.z } , null , o.time , Quint.easeInOut ); io.addEventListener( TweenEvent.COMPLETE , tweenEventCompleteHandler , false , 0 , true ); io.play(); } private function tweenEventCompleteHandler( $evt:TweenEvent ):void { var io:IObjectTween = $evt.target as IObjectTween; io.removeEventListener( TweenEvent.COMPLETE , tweenEventCompleteHandler ); _isAnimationVector[int( io.target.name )] = false; } private function shuffleArray( arr:Array ):Array { var len:uint, reArr:Array , m:uint , n:*; len = arr.length; reArr = arr; while ( len ) { m = Math.floor(Math.random() * len ); n = reArr[--len]; reArr[len] = reArr[m]; reArr[m] = n ; } return reArr; } } } forked from: 【AS100本ノック】12回目:時計