// forked from mtok's コロコロ // forked from mtok's 任意の点を中心に回転させる。サンプル package { import flash.events.Event; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.text.AntiAliasType; import flash.utils.Timer; import flash.geom.Rectangle; import flash.geom.Matrix; /** * ... * @author ... */ public class CoroCoro extends Sprite { private var screen:Sprite; private var bmpData:BitmapData; private var timer:Timer; private var timer2:Timer; private var timer3:Timer; private var boxes:Array; private var tile:Sprite; private var clipRect:Rectangle; private var blockSize:Number = 120; private var fillMat:Matrix; public function CoroCoro() { addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { if (e) { removeEventListener(e.type, arguments.callee); } var w:int = stage.stageWidth; var h:int = stage.stageHeight; bmpData = new BitmapData(blockSize, blockSize, true, 0x00000000); screen = new Sprite(); addChild(screen); timer = new Timer(1000 / 24); timer.addEventListener(TimerEvent.TIMER, timerHandler); timer2 = new Timer(1000); timer2.addEventListener(TimerEvent.TIMER, timer2Handler); timer3 = new Timer(4000); timer3.addEventListener(TimerEvent.TIMER, timer3Handler); tile = new Sprite() //addChild(tile); boxes = new Array(); var b:Box; var i:int = -blockSize; var j:int = -blockSize; while (i <= blockSize*2) { j = -blockSize; while (j <= blockSize*2) { b = Box.createBox(blockSize, blockSize); tile.addChild(b); boxes.push(b); b.x = j; b.y = i; j += blockSize; } i += blockSize; } fillMat = new Matrix(); clipRect = new Rectangle(0, 0, blockSize, blockSize); redraw(); stage.addEventListener(MouseEvent.MOUSE_DOWN, stageMouseDownHandler); } private function timer3Handler(e:TimerEvent):void { var scale:Number = int(Math.random() * 2 + 0.5) + 1; fillMat.identity(); fillMat.scale(1/scale, 1/scale); } private function timer2Handler(e:TimerEvent):void { move(); } private function stageMouseDownHandler(e:MouseEvent):void { timer.running ? timer.stop() : timer.start(); timer2.running ? timer2.stop(): timer2.start(); timer3.running ? timer3.stop(): timer3.start(); } private function move():void { var i:int; var b:Box; var dir:int = Math.floor(Math.random() * 4); switch(dir) { case 0://up for (i = 0; i < boxes.length; i++) { b = boxes[i] as Box; b.addEventListener(Event.COMPLETE, boxUpCompleteHandler); b.moveUp(); } break; case 1://right for (i = 0; i < boxes.length; i++) { b = boxes[i] as Box; b.addEventListener(Event.COMPLETE, boxRightCompleteHandler); b.moveRight(); } break; case 2://down for (i = 0; i < boxes.length; i++) { b = boxes[i] as Box; b.addEventListener(Event.COMPLETE, boxDownCompleteHandler); b.moveDown(); } break; case 3://left default: for (i = 0; i < boxes.length; i++) { b = boxes[i] as Box; b.addEventListener(Event.COMPLETE, boxLeftCompleteHandler); b.moveLeft(); } break; } } private function boxUpCompleteHandler(e:Event):void { var b:Box = e.target as Box; b.removeEventListener(e.type, arguments.callee); b.y += b.height; } private function boxRightCompleteHandler(e:Event):void { var b:Box = e.target as Box; b.removeEventListener(e.type, arguments.callee); b.x -= b.width; } private function boxDownCompleteHandler(e:Event):void { var b:Box = e.target as Box; b.removeEventListener(e.type, arguments.callee); b.y -= b.height; } private function boxLeftCompleteHandler(e:Event):void { var b:Box = e.target as Box; b.removeEventListener(e.type, arguments.callee); b.x += b.width; } private function redraw():void { bmpData.fillRect(bmpData.rect, 0xffffff); bmpData.draw(tile, null, null, null, clipRect); screen.graphics.clear(); screen.graphics.beginBitmapFill(bmpData, fillMat, true, true); screen.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); screen.graphics.endFill(); } private function timerHandler(e:TimerEvent):void { //move(); redraw(); } } } import flash.events.MouseEvent; import flash.events.Event; import flash.display.Sprite; import flash.display.DisplayObject; import caurina.transitions.Tweener; import flash.geom.Point; import flash.geom.Rectangle; import flash.geom.Matrix; import caurina.transitions.Equations; internal class Box extends Sprite { private var obj:Object; private var transition:String = "easeInOutCubic"; private var time:Number = 1; public function Box() { super(); } public static function createBox(w:Number, h:Number, color:uint = 0xFD5322):Box { var padding:Number = w * 0.1; var b:Box = new Box(); b.graphics.beginFill(0x000000, 0); b.graphics.drawRect(0, 0, w, h); b.graphics.endFill(); b.graphics.beginFill(color); b.graphics.drawRect(padding*0.5, padding*0.5, w-padding, h-padding); b.graphics.endFill(); b.graphics.beginFill(0xFFFFFF); b.graphics.drawCircle(w*0.5, w*0.2, padding); b.graphics.endFill(); b.buttonMode = true; b.useHandCursor = true; return b; } public function move(direction:String):void { if (Tweener.isTweening(obj)) { //trace('is tweening'); return; } obj = { angle:0 }; Tweener.addTween(obj, { angle:Math.PI*0.5, time:time, transition:transition, onStartScope:this, onStart:function():void { var rect:Rectangle = this.getRect(this.parent); obj.matrix = this.transform.matrix; obj.p = getPole(rect, direction); }, onUpdateScope:this, onUpdateParams:[obj], onUpdate:onUpdate, onCompleteScope:this, onCompleteParams:[obj], onComplete:onComplete }); } public function getPole(rect:Rectangle, dir:String):Point { var p:Point; switch(dir) { case BoxDirection.LEFT: p = new Point(rect.x, rect.y); break; case BoxDirection.RIGHT: p = new Point(rect.x + rect.width, rect.y + rect.height); break; case BoxDirection.UP: p = new Point(rect.x + rect.width, rect.y); break; case BoxDirection.DOWN: p = new Point(rect.x, rect.y + rect.height); break; default: throw(new Error("invalid dir "+dir)); } return p; } public function moveUp():void { move(BoxDirection.UP); } public function moveDown():void { move(BoxDirection.DOWN); } public function moveLeft():void { move(BoxDirection.LEFT); } public function moveRight():void { move(BoxDirection.RIGHT); } public function onComplete(params:Object):void { Tweener.removeTweens(params); dispatchEvent(new Event(Event.COMPLETE)); } public function onUpdate(params:Object):void { rotateAt(this, params); } public function isMoving():Boolean { return obj != null; } private function rotateAt(d:DisplayObject, params:Object):void { var m:Matrix = params.matrix.clone(); var m2:Matrix = new Matrix(); m2.translate( -params.p.x, -params.p.y); m2.rotate(params.angle); //trace(params.angle); m2.translate(params.p.x, params.p.y); m.concat(m2); d.transform.matrix = m; } } internal class BoxDirection { public static const UP:String = "up"; public static const DOWN:String = "down"; public static const LEFT:String = "left"; public static const RIGHT:String = "right"; } CoroCoro Tiling