// Hellow Snow!!! // forked from Saqoosha's Snow package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; import flash.filters.BlurFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; [SWF(width=465, height=465, backgroundColor=0x0, frameRate=120)] public class Snow extends Sprite { private static const WIND_X:Number = 40; private static const WIND_Y:Number = -15; private static const GRAVITY:Number = 10; private static const START_Y:Number = 200; private var _canvas:BitmapData; private var _textBmp:BitmapData; private var _glow:BitmapData; private var _glowMtx:Matrix; private var _snow:Array; private var _snow_prepare:Array; private var _text:TextField; private var _log:TextField; public function Snow() { stage.scaleMode = "noScale"; _text = new TextField(); _text.defaultTextFormat = new TextFormat('Verdana', 48, 0xffffff, true); _text.text = "Hello Snow!!!"; _text.autoSize = "left"; _textBmp = new BitmapData(465, 465, false, 0x000000); this._canvas = new BitmapData(465, 465, false, 0x000000); //this.addChild(new Bitmap(_textBmp)); this.addChild(new Bitmap(this._canvas)); this._snow = []; this._snow_prepare = []; this._glow = new BitmapData(465 / 4, 465 / 4, false, 0x0); // キラキラを描く用のん。カンバスの 4 分の 1 のサイズ var bm:Bitmap = this.addChild(new Bitmap(this._glow, PixelSnapping.NEVER, true)) as Bitmap; // smoothing を true にして配置 bm.scaleX = bm.scaleY = 4; // 4 倍にする。 bm.blendMode = BlendMode.ADD; // 加算モードで合成 this._glowMtx = new Matrix(0.25, 0, 0, 0.25); // init _snow_prepare this.addEventListener(Event.ENTER_FRAME, function(event:Event):void{ for(var i:int = 0; i < 3; i++){ if(_snow_prepare.length){ var index:int = Math.random() * Math.min(30, _snow_prepare.length); var particle:SnowParticle = _snow_prepare[index]; _snow_prepare.splice(index, 1); _textBmp.setPixel(particle.x, particle.y, 0x000000); _snow.push(particle); } } if(_snow_prepare.length || _snow.length){ update(null); }else{ init(); } }); init(); } public function init():void{ var mtx:Matrix = new Matrix(); mtx.ty = START_Y; _textBmp.draw(_text, mtx); var rect:Rectangle = _textBmp.getColorBoundsRect(0, 0, false); for(var x:int = rect.left; x <= rect.right; x++){ for(var y:int = rect.top; y <= rect.bottom; y++){ var col:uint = _textBmp.getPixel(x, y); if(col != 0x000000){ _snow_prepare.push(new SnowParticle(x, y, col, Math.random(), -Math.random())); } } } _snow_prepare.sort(function(a:SnowParticle, b:SnowParticle):int{ var _a:int = a.x + a.y * 3; var _b:int = b.x + b.y * 3; return _a > _b ? 1 : _a == _b ? 0 : -1; }); } // 雪を動かすよーー public function update(e:Event):void { this._canvas.lock(); // いっぱい setPixel するときは必ず lock しよう this._canvas.fillRect(this._canvas.rect, 0x0); // カンバスをクリア this._canvas.copyPixels(_textBmp, _textBmp.rect, new Point(0, 0)); var n:int = this._snow.length; var d:Number = 1.0; var wind_x:Number = (Math.random() > .4 ? WIND_X : 0) / 1000; var wind_y:Number = (GRAVITY + (Math.random() > .6 ? WIND_Y : WIND_Y / 2)) / 1000; while (n--) { var p:SnowParticle = this._snow[n]; p.vx += wind_x * p.s; p.vy += wind_y * p.s; p.vx *= 0.99; // 空気抵抗 p.vy *= 0.99; // y 方向にも p.x += p.vx; // 動かす p.y += p.vy; this._canvas.setPixel(p.x, p.y, p.c); // 雪 1 粒描く if (p.y < 0 || p.y > this.stage.stageHeight || p.x > this.stage.stageWidth) { // もし画面外にでちゃったら this._snow.splice(n, 1); // とりのぞく } } this._canvas.unlock(); // lock したやつは必ず unlock this._glow.draw(this._canvas, this._glowMtx); // キラキラを描く } } } class SnowParticle { public var x:Number; public var y:Number; public var vx:Number; public var vy:Number; public var s:Number; public var c:int; public function SnowParticle(x:Number, y:Number, color:uint, vx:Number, vy:Number) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.s = 1; this.c = color; } } Hello Snow!!!