package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.ActivityEvent; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.media.Video; import flash.utils.Timer; public class NewClass extends Sprite { private static const _X_COUNT:uint = 4; private static const _Y_COUNT:uint = 4; private var _block16Width:Number; private var _block16Height:Number; private var _margin:Number = 12; private var _video:Video; private var _bmds:Array; private var _block16s:Array; private var _blankBlock16:Block16; private var _base:Sprite; public function NewClass():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.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; var webCam:WebCam = new WebCam(); webCam.addEventListener( ActivityEvent.ACTIVITY, _onWebCamActivity ); webCam.initialize( null, 1000, false ); } //-------------------------------------- // //-------------------------------------- private function _onWebCamActivity( event:ActivityEvent ):void { if ( event.activating ) { WebCam( event.target ).removeEventListener( ActivityEvent.ACTIVITY, _onWebCamActivity ); _video = WebCam( event.target ).video; _block16Width = _video.width / _X_COUNT; _block16Height = _video.height / _Y_COUNT; _block16s = new Array(); _bmds = new Array(); _base = addChild( new Sprite() ) as Sprite; for ( var idxY:uint = 0; idxY < _Y_COUNT; idxY++ ) { var array:Array = new Array(); for ( var idxX:uint = 0; idxX < _X_COUNT; idxX++ ) { var block16:Block16 = _base.addChild( new Block16( _block16Width, _block16Height, 4 * idxY + idxX + 1 ) ) as Block16; array.push( block16 ); block16.x = ( _block16Width + _margin ) * idxX; block16.y = ( _block16Height + _margin ) * idxY; block16.addEventListener( MouseEvent.CLICK, _onBlock16Click ); if ( idxX == 3 && idxY == 3 ) { _blankBlock16 = block16; block16.isBlank = true; } var bmd:BitmapData = new BitmapData( _video.width / _X_COUNT, _video.height / _Y_COUNT, false, 0 ); var bm:Bitmap = _base.addChild( new Bitmap() ) as Bitmap; bm.bitmapData = bmd; block16.setBitmap( bm ); _bmds.push( bmd ); } _block16s.push( array ); } addEventListener( Event.ENTER_FRAME, _onEnterFrame ); stage.addEventListener( Event.RESIZE, _onStageResize ); _update(); _randomise(); } } private function _onStageResize(e:Event):void { _update(); } private function _onTimer(e:TimerEvent):void { var point:Point = indexXYOf( _block16s, _blankBlock16 ); var index:uint; if ( Math.random() < 0.5 ) { index = Math.floor( ( _Y_COUNT - 1 ) * Math.random() ); if ( point.y <= index ) { index++; } _move( new Point( point.x, index ) ); } else { index = Math.floor( ( _X_COUNT - 1 ) * Math.random() ); if ( point.x <= index ) { index++; } _move( new Point( index, point.y ) ); } } private function _onTimerComplete(e:TimerEvent):void { mouseEnabled = true; alpha = 1; } private function _onEnterFrame(e:Event):void { var src:BitmapData = new BitmapData( _video.width, _video.height ); src.draw( _video ); waffle( src, _X_COUNT, _Y_COUNT, _bmds ); } private function _onBlock16Click( event:MouseEvent ):void { var point:Point = indexXYOf( _block16s, Block16( event.currentTarget ) ); _move( new Point( point.y, point.x ) ); } //-------------------------------------- // //-------------------------------------- private function _update():void { _base.scaleX = _base.scaleY = 1; if ( 0.8 * stage.stageWidth < _base.width ) { _base.scaleX = _base.scaleY = 0.8 * stage.stageWidth / _base.width; } if ( 0.8 * stage.stageHeight < _base.height ) { _base.scaleX = _base.scaleY = 0.8 * stage.stageHeight / _base.height; } _base.x = 0.5 * ( stage.stageWidth - _base.width ); _base.y = 0.5 * ( stage.stageHeight - _base.height ); } private function _randomise( count:uint = 50 ):void { var timer:Timer = new Timer( 100, count ); timer.addEventListener( TimerEvent.TIMER, _onTimer ); timer.addEventListener( TimerEvent.TIMER_COMPLETE, _onTimerComplete ); timer.start(); mouseEnabled = false; alpha = 0.5; } private function _move( clickPoint:Point ):void { var block16s:Array = new Array(); block16s = clone2d( _block16s ); var point:Point = indexXYOf( _block16s, _blankBlock16 ); var blankPoint:Point = new Point( point.y, point.x ); var idx:uint; var block16:Block16; if ( blankPoint.x == clickPoint.x ) { for ( idx = clickPoint.y; idx < blankPoint.y; idx++ ) { block16 = _block16s[ idx ][ clickPoint.x ]; _moveTo( block16, block16.x, ( _block16Height + _margin ) * ( idx + 1 ) ); block16s[ idx + 1 ][ clickPoint.x ] = block16; } for ( idx = blankPoint.y + 1; idx < clickPoint.y + 1; idx++ ) { block16 = _block16s[ idx ][ clickPoint.x ]; _moveTo( block16, block16.x, ( _block16Height + _margin ) * ( idx - 1 ) ); block16s[ idx - 1 ][ clickPoint.x ] = block16; } block16s[ clickPoint.y ][ clickPoint.x ] = _blankBlock16; _moveTo( _blankBlock16 , ( _block16Width + _margin ) * clickPoint.x , ( _block16Height + _margin ) * clickPoint.y ); } if ( blankPoint.y == clickPoint.y ) { for ( idx = clickPoint.x; idx < blankPoint.x; idx++ ) { block16 = _block16s[ clickPoint.y ][ idx ]; _moveTo( block16, ( _block16Width + _margin ) * ( idx + 1 ), block16.y ); block16s[ clickPoint.y ][ idx + 1 ] = block16; } for ( idx = blankPoint.x + 1; idx < clickPoint.x + 1; idx++ ) { block16 = _block16s[ clickPoint.y ][ idx ]; _moveTo( block16, ( _block16Width + _margin ) * ( idx - 1 ), block16.y ); block16s[ clickPoint.y ][ idx - 1 ] = block16; } block16s[ clickPoint.y ][ clickPoint.x ] = _blankBlock16; _moveTo( _blankBlock16 , ( _block16Width + _margin ) * clickPoint.x , ( _block16Height + _margin ) * clickPoint.y ); } _block16s = block16s; } private function _moveTo( block16:Block16, targetX:Number, targetY:Number, time:Number = 0.3 ):void { block16.x = targetX; block16.y = targetY; } public static function indexXYOf( array:Array, target:* ):Point { for ( var idxX:uint = 0; idxX < array.length; idxX++ ) { for ( var idxY:uint = 0; idxY < array[ idxX ].length; idxY++ ) { if ( array[ idxX ][ idxY ] == target ) { return new Point( idxX, idxY ); } } } return new Point( -1, -1 ); } public static function clone2d( array:Array ):Array { var result:Array = new Array(); for ( var idx1:uint = 0; idx1 < array.length; idx1++ ) { result[ idx1 ] = new Array(); for ( var idx2:uint = 0; idx2 < array[ idx1 ].length; idx2++ ) { result[ idx1 ][ idx2 ] = array[ idx1 ][ idx2 ]; } } return result; } public static function waffle( src:BitmapData, xDivisionCount:uint, yDivisionCount:uint, targets:Array = null ):Array { var dividedWidth:Number = src.width / xDivisionCount; var dividedHeight:Number = src.height / yDivisionCount; var bmds:Array = ( targets == null ) ? new Array() : targets; for ( var idxY:uint = 0; idxY < yDivisionCount; idxY++ ) { for ( var idxX:uint = 0; idxX < xDivisionCount; idxX++ ) { var rect:Rectangle = new Rectangle( idxX * dividedWidth , idxY * dividedHeight , dividedWidth , dividedHeight ); var bmd:BitmapData; if ( targets == null ) { bmd = new BitmapData( dividedWidth, dividedHeight ); bmds.push( targets ); } else { bmd = bmds[ idxY * xDivisionCount + idxX ]; } bmd.copyPixels( src, rect, new Point() ); } } return bmds; } } } import flash.display.Bitmap; import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.filters.GlowFilter; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import flash.utils.getQualifiedClassName; class Block16 extends Sprite{ private var _base:Sprite; private var _mask:Sprite; private var _baseWidth:Number; private var _baseHeight:Number; private var _isBlank:Boolean; private var _index:uint; public function Block16( baseWidth:Number, baseHeight:Number, index:uint ) { _baseWidth = baseWidth; _baseHeight = baseHeight; _index = index; _base = addChild( new Sprite() ) as Sprite; _base.graphics.beginFill( 0 ); _base.graphics.drawRect( 0, 0, _baseWidth, _baseHeight ); _base.graphics.endFill(); _mask = addChild( new Sprite() ) as Sprite; _base.mask = _mask; var tf:TextField = new TextField(); tf.defaultTextFormat = new TextFormat( "Arial", Math.floor( _baseWidth / 4 ), 0xeeeeec, true ); tf.text = String( " " + _index + " " ); tf.autoSize = TextFieldAutoSize.LEFT; tf.selectable = false; var bm:Bitmap = _base.addChild( convertTFtoBitmap( tf ) ) as Bitmap; var shadow:Shape = _base.addChildAt( new Shape(), 0 ) as Shape; shadow.graphics.beginFill( 0, 0.5 ); shadow.graphics.drawRect( 0, 0, bm.width, bm.height ); shadow.graphics.endFill(); filters = new Array( new GlowFilter( 0x999999 ) ); addEventListener( MouseEvent.ROLL_OVER, _onRollOver ); addEventListener( MouseEvent.ROLL_OUT, _onRollOut ); buttonMode = true; _update(); } public function convertTFtoBitmap( tf:TextField ):Bitmap { var bmd:BitmapData = new BitmapData( tf.width, tf.height, true, 0x00ffffff ); bmd.draw( tf ); return new Bitmap( bmd ); } public function setBitmap( bm:Bitmap ):void { _base.addChildAt( bm, 0 ); } public function get isBlank():Boolean { return _isBlank; } public function set isBlank(value:Boolean):void { _isBlank = value; mouseEnabled = _isBlank; visible = !_isBlank; } public function get index():uint { return _index; } public function set index(value:uint):void { _index = value; } private function _update():void { _mask.graphics.clear(); _mask.graphics.beginFill( 0 ); _mask.graphics.drawRoundRect( 0, 0, _baseWidth, _baseHeight, 10 ); _mask.graphics.endFill(); } private function _onRollOver(e:MouseEvent):void { _base.alpha = 0.5; } private function _onRollOut(e:MouseEvent):void { _base.alpha = 1; } } import flash.display.BitmapData; import flash.events.ActivityEvent; import flash.events.EventDispatcher; import flash.events.TimerEvent; import flash.media.Camera; import flash.media.Video; import flash.utils.Timer; class WebCam extends EventDispatcher{ private var _camera:Camera; private var _video:Video; private var _filters:Array; private var _cameraWidth:Number; private var _cameraHeight:Number; private var _cameraFPS:Number; private var _verbose:Boolean; public function WebCam( cameraWidth:Number = 640 , cameraHeight:Number = 480 , cameraFPS:Number = 30 ) { _cameraWidth = cameraWidth; _cameraHeight = cameraHeight; _cameraFPS = cameraFPS; } public function initialize( filters:Array = null, checkInterval:Number = 1000, verbose:Boolean = false ):void { _filters = filters; _verbose = verbose; if ( _checkAvailability() ) { _initialize(); } else { var timer:Timer = new Timer( checkInterval ); timer.addEventListener( TimerEvent.TIMER, _onTimer ); timer.start(); } } public function get camera():Camera { return _camera; } public function get video():Video { return _video; } public function get bitmapData():BitmapData { var bmd:BitmapData = new BitmapData( _video.width, _video.height ); bmd.draw( _video ); return bmd; } private function _initialize():void { _camera.setMode( _cameraWidth, _cameraHeight, _cameraFPS ); _video = new Video( _camera.width, _camera.height ); _video.attachCamera( _camera ); if ( _filters != null ) { _video.filters = _filters; } _camera.addEventListener( ActivityEvent.ACTIVITY, _onCameraActivity ); } private function _onTimer( event:TimerEvent ):void { if ( _checkAvailability() ) { _initialize(); Timer( event.target ).removeEventListener( TimerEvent.TIMER, _onTimer ); Timer( event.target ).stop(); } } private function _checkAvailability():Boolean { _camera = Camera.getCamera( "0" ); if ( _camera != null ) { return true; } else { return false; } } private function _onCameraActivity( event:ActivityEvent ):void { if ( _verbose ) { var text:String = new String("\n"); text = text.concat( " activityLevel :", _camera.activityLevel, "\n" ); text = text.concat( " bandwidth :", _camera.bandwidth, "\n" ); text = text.concat( " currentFPS :", _camera.currentFPS, "\n" ); text = text.concat( " fps :", _camera.fps, "\n" ); text = text.concat( " height :", _camera.height, "\n" ); text = text.concat( " index :", _camera.index, "\n" ); text = text.concat( "keyFrameInterval :", _camera.keyFrameInterval, "\n" ); text = text.concat( " motionLevel :", _camera.motionLevel, "\n" ); text = text.concat( " name :", _camera.name, "\n" ); text = text.concat( " quality :", _camera.quality, "\n" ); text = text.concat( " width :", _camera.width, "\n" ); trace( "[Cam._onCameraActivity] ", event.activating ); trace( text ); text = "\n"; text = text.concat( " deblocking :", _video.deblocking, "\n" ); text = text.concat( " smoothing :", _video.smoothing, "\n" ); text = text.concat( "videoHeight :", _video.videoHeight, "\n" ); text = text.concat( " videoWidth :", _video.videoWidth, "\n" ); trace( "[Cam._onVideoActivate] " ); trace( text ); } dispatchEvent( event ); } } ウェブカム16パズル