In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

暑いから雪を降らしてみる(4) PerlinNoiseで風吹いてるVer

アニメーション用の設定をしておくよ
/**
 * Copyright 7kamura ( http://wonderfl.net/user/7kamura )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zh2j
 */

// forked from 7kamura's 暑いから雪を降らしてみる(3) 文字ありVer
// forked from 7kamura's 暑いから雪を降らしてみる(2) キラキラVer
// forked from 7kamura's 暑いから雪を降らしてみる(1) 普通に落ちるだけVer
package {
    import flash.display.Sprite;
    import flash.display.*;
    import flash.geom.Rectangle;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFieldAutoSize;
    import flash.filters.BlurFilter;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
 
    // アニメーション用の設定をしておくよ
	[SWF(width=465, height=465, backgroundColor=0x0, frameRate=60)]
    import flash.geom.Matrix;
    import flash.geom.Point;
    public class Main extends Sprite {
		public static const WIDTH:Number = 465;
		public static const HEIGHT:Number = 465;
		public static const GRAVITY:Number = 0.02;
    		private var rect:Rectangle;
    		private var canvas:BitmapData;
    		private var textBmd:BitmapData;
    		private var glowBmd:BitmapData;
    		private var noiseBmd:BitmapData;
    		private var particleList:Array;
    		private var glowMatrix:Matrix;
    		private var timer:Timer;
    		
        public function Main() {
        		if(stage) init();
        }
        private function init():void {
        		// ここにParticleを描画していくよ
        		canvas = new BitmapData(WIDTH, HEIGHT, false, 0x0);
        		addChild(new Bitmap(canvas));
        		
        		// これを上から被せてキラキラ表示するよ
        		// 1/4の大きさでcanvasをコピーしてから4倍に拡大して被せることでキラキラを演出するよ
        		// BlendMode.ADDのおかげで、透明のシートを被せたような感じになってるよ
        		// Bitmapの生成時に、smoothingをtrueにして滑らかに表示しているよ
        		// 拡大率をglowMatrixに保存しておいて、後でコピーしたcanvasを縮小するときに使うよ
        		glowBmd = new BitmapData(WIDTH/4, HEIGHT/4, false, 0x0);
        		var glowBmp:Bitmap = addChild(new Bitmap(glowBmd, PixelSnapping.NEVER, true)) as Bitmap;
        		glowBmp.blendMode = BlendMode.ADD;
        		glowBmp.scaleX = glowBmp.scaleY = 4;
        		glowMatrix = new Matrix(1/4, 0, 0, 1/4);
        		
        		// Particle達はここに入れておくよ
        		particleList = new Array;
        		
        		// Particleで彩られる予定の文字データを用意するよ
        		createText();
        		
        		// 風を演出するためのParlinNoiseを作成するよ
        		createPerlinNoise();
        		
        		// 毎フレームごとに描画を更新してもらうよ
        		addEventListener(Event.ENTER_FRAME, update);
        		
        		// 10秒ごとに風向きを変えるよ
        		timer = new Timer(10000);
        		timer.addEventListener(TimerEvent.TIMER, onTimer);
        		timer.start();
        		
        		// クリックで最初からやり直してもらうよ
        		stage.addEventListener(MouseEvent.CLICK, reset);
        }
        private function reset(e:Event):void { 
        		init();
        }
        
        private function onTimer(e:Event):void {
        		createPerlinNoise();
        }
        
        private function update(e:Event):void {
        		// Canvasを一旦クリアするよ
        		canvas.fillRect(canvas.rect, 0x0);
        		
        		// Particleを10個つくるよ
        		var p_num:Number = 10;
        		while(p_num--) {
        			createParticle(Math.random()*WIDTH, 0);
        		}
        			
        		canvas.lock();
        		var n:Number = particleList.length;
        		var d:Number;
        		while(n--) {
        			var p:Particle = particleList[n];
        			p.vy += GRAVITY; // 重力加速度
        			p.vx *= 0.99; // 空気抵抗
        			p.vy *= 0.99;
        			
        			// 文字の上(白い部分)に来ると速度を落とすよ
        			d = 1 - (textBmd.getPixel(p.x, p.y) / 0xFFFFFF) * 0.3;
        			p.vx *= d;
        			p.vy *= d;
        			
        			// noiseBmdによってランダムに移動するよ
        			// 赤色成分の値によってx方向の速度を変えているよ
        			var color:uint = noiseBmd.getPixel(p.x, p.y);
        			var r:uint = color >> 16 & 0xFF;
        			p.vx += ((r - 128) / 0xFF) * 0.05;
        			
        			p.x += p.vx; // 移動
        			p.y += p.vy;
        			canvas.setPixel(p.x, p.y, p.c);
        			
        			// 画面外に出たParticleを抹消するよ
        			if (p.x > WIDTH || p.x < 0 || p.y > HEIGHT || p.y < 0) {
        				particleList.splice(n, 1);
        			}
        		}
        		
        		// キラキラを上から被せるよ
        		glowBmd.draw(canvas, glowMatrix);
        		
        		canvas.unlock();
        }
        
    		private function createText():void {
    			var tfld:TextField = new TextField();
    			tfld.autoSize = TextFieldAutoSize.LEFT;
    			tfld.defaultTextFormat = new TextFormat("Verdana", 50, 0xFFFFFF, true);
    			tfld.text = "Gakuweb";
    			tfld.x = (canvas.width - tfld.width) / 2;
    			tfld.y = (canvas.height- tfld.height)/ 2;
    			
    			// tfldをBitmapDataに変換するよ
    			textBmd = new BitmapData(WIDTH, HEIGHT, false, 0x0);
    			textBmd.applyFilter(textBmd, textBmd.rect, new Point(0, 0), new BlurFilter(4,4));
    			textBmd.draw(tfld, tfld.transform.matrix);
    			
    			/* For Debug
    			addChild(tfld);
    			*/
    		}
    		
    		private function createPerlinNoise():void {
    			noiseBmd = new BitmapData(WIDTH, HEIGHT, false, 0x0);
    			var randomSeed:uint = Math.floor(Math.random() * 0xFFFF);
    			noiseBmd.perlinNoise(WIDTH, HEIGHT, 1, randomSeed, false, true, 1);
    			    			
    			/* For Debug
    			addChild(new Bitmap(noiseBmd));
    			*/
    		}
    		
    		private function createParticle(x:Number, y:Number, vx:Number = 0, vy:Number = 0, c:uint = 0xFFFFFF):void {
    			var p:Particle = new Particle();
    			p.x = x;
    			p.y = y;
    			p.vx = vx;
    			p.vy = vy;
    			p.c = c;
    			particleList.push(p);
    		}
    }
}

class Particle {
	public var x:Number;
	public var y:Number;
	public var vx:Number;
	public var vy:Number;
	public var c:uint;
	
	public function init():void {
		x = 0;
		y = 0;
		vx = 0;
		vy = 0;
		c = 0xFFFFFF;
	}
}