package { import flash.display.*; import flash.events.*; import flash.filters.*; import flash.geom.*; import flash.text.*; import flash.utils.*; [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)] public class Main extends MovieClip { private static var POINT_ZERO:Point = new Point(); private static var TRANSFORM_COLOR:ColorTransform = new ColorTransform(0.7, .1, 1, .85, 0, 0, 0, 0); private static var FILTER_BLUR:BlurFilter = new BlurFilter(4, 4, BitmapFilterQuality.LOW); private static var MENU_STR:String="シャッセ斬り"; private var menuParticles:Dictionary; private var film:BitmapData; private var mc:MovieClip; private var _flag:Number = 1; public function Main() { film = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0); addChild(new Bitmap(film)); var fmt:TextFormat = new TextFormat(null, 64, 0xcccc66, true); var txt:TextField = new TextField(); txt.autoSize = TextFieldAutoSize.LEFT; txt.defaultTextFormat = fmt; txt.text = MENU_STR; var bmd:BitmapData = new BitmapData(txt.width, txt.height, true, 0); bmd.draw(txt); mc = new MovieClip(); mc.addChild(new Bitmap(bmd)); mc.alpha = .2; mc.x = stage.stageWidth/2-mc.width/2; mc.y = stage.stageHeight / 2 - txt.height / 2; addChild(mc); createParticle(); drawCanvas(); addEventListener(Event.ENTER_FRAME, step); var myTimer:Timer = new Timer(5000); myTimer.addEventListener(TimerEvent.TIMER, xTimer); myTimer.start() } private function xTimer(e:TimerEvent):void { var ps:Vector.<Particle> = menuParticles[mc]; var i:uint = ps.length; if (_flag) { _flag = 0; while (i--) { ps[i].reverse = true; } }else { _flag = 1; while (i--) { ps[i].reverse = false; } } } private function createParticle():void { menuParticles = new Dictionary(); var len:Number = 600; var original:BitmapData = new BitmapData(mc.width, mc.height, true, 0); original.draw(mc); var ps:Vector.<Particle> = new Vector.<Particle>(); var baseX:Number = mc.x; var baseY:Number = mc.y; for (var w:uint=0; w<original.width; w++) { for (var h:uint=0; h<original.height; h++) { var color:uint = original.getPixel32(w, h); if (!color) continue; var angle:Number = Math.random() * Math.PI * 2; var p:Particle = new Particle(); p.color = color; p.x = w + baseX; p.y = h + baseY; p.end = new Point(p.x, p.y); p.start = new Point(Math.cos(angle) * len + baseX, Math.sin(angle) * len + baseY); p.x = Math.random() * 1000-250 ; p.y = Math.random() * 1000-250 ; ps.push(p); } } original.dispose(); menuParticles[mc] = ps; } private function step(event:Event):void { drawCanvas(); } private function drawCanvas():void { film.lock(); film.colorTransform(film.rect, TRANSFORM_COLOR); film.applyFilter(film, film.rect, POINT_ZERO, FILTER_BLUR); var ps:Vector.<Particle> = menuParticles[mc]; var m:uint = ps.length; while (m--) { var p:Particle = ps[m]; film.setPixel32(p.x, p.y, p.color); p.update(); } film.unlock(); } } } import flash.geom.*; class Particle { public var mcName:String; public var isAlive:Boolean = true; public var x:Number = 0; public var y:Number = 0; public var color:uint = 0; public var start:Point; public var end:Point; private var _reverse:Boolean = false; private var _vx:Number = 0; private var _vy:Number = 0; private var _tick:uint = 0; private var rnd:Number = Math.random() * 100; private var rnd2:Number = Math.random() * 0.07 + 0.09 ; private var rnd3:Number= (Math.random() > 0.5)? 1:-1; public function get reverse():Boolean { return _reverse; } public function set reverse(reverse:Boolean):void { _reverse = reverse; isAlive = true; } public function Particle() { var strength:Number = Math.random() * 4; var angle:Number = Math.random() * Math.PI * 2; _vx = strength * Math.cos(angle); _vy = strength * Math.sin(angle); } public function update():void { if (!isAlive) return; var speed:Number, target:Point, delta:Point; target = _reverse ? start : end; if (_reverse) { _tick++; var t:Number = _tick / 60; x += .5 * t + _vx; y += -.5 * t + _vy; } else { _tick = 0; delta = target.subtract(new Point(x, y)); var kyori:Number = x-target.x ; x += delta.x * rnd2; y = target.y+rnd*Math.sin( kyori*Math.PI/180)*rnd3; } if (Math.abs(target.x - x) <= 1 && Math.abs(target.y - y) <= 1) { x = target.x; y = target.y; isAlive = false; } } } 拡散と収束