forked from: 雲間から光が差し込む forked from: CloudEffect

by angerfish forked from 雲間から光が差し込む forked from: CloudEffect (diff: 1)
♥0 | Line 113 | Modified 2009-06-08 14:05:31 | MIT License
play

ActionScript3 source code

/**
 * Copyright angerfish ( http://wonderfl.net/user/angerfish )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sosK
 */

// forked from nemu90kWw's 雲間から光が差し込む forked from: CloudEffect
// forked from tail_y's CloudEffect
package
{
	/*
	 若干立体感のある、雲っぽい映像を作るよ。
	 はっきり言って重いので、実用性がちょっと無いよ!!
	 その代わり、リアルタイムで色合いとか変えられるから、時間に合わせて夕焼けになったりできるかも。
	 
	 仕組み的にはPhotoShopでの常套手段をFlashで再現したもの。
	 数値を変えるとかなりリアルなのも作れるけど、これ以上立体感を出すには他の工夫が必要。
	 台形変形とか、影の位置をずらしたりとかできれば・・・。
	 
	 雲模様の生成が遅いのはなんとかならないかな~
	 1オクターブずつ用意して、横にずれた分だけを新しく生成するとかさ。
	 ちょっと考えてみたけど頭痛くなったからやらなかったよ。
	 */
        /*
         びかーっとさせてみた。
         重いよ!!
        */
	
	import flash.display.*;
	import flash.events.*;
	import flash.filters.*;
	import flash.geom.*;
	
	import net.hires.debug.Stats;

	public class CloudEffect1 extends Sprite
	{
		public static const STAGE_W:uint = 465;
		public static const STAGE_H:uint = 465;
		
		public static const _H_RATE:Number = 4;	// 上下の圧縮割合
		
		// 雲模様関係
		private var _perlinNoiseBitmapData:BitmapData;
		private var _seed:int = Math.random()*int.MAX_VALUE;
		private var _perlinNoiseSize:Number = 0.20;	// 雲模様を画面全体に描画するのは重くて無理なので、サイズを減らす。
		private var _perlinNoiseSizeW:int = STAGE_W*_perlinNoiseSize;
		private var _perlinNoiseSizeH:int = STAGE_H*_perlinNoiseSize*_H_RATE;
		private var _cloudSize:int = _perlinNoiseSize * 100;
		private var _octaves:int = 4;	// 雲模様オクターブ数。レイヤー数みたいなもの。多いほど細かいけど、死ぬほど重くなる。
		private var _offsetList:Array = [];	// 雲のズレ。オクターブの数だけPointが必要。
		private var _offsetSpeedListX:Array = [0.4, 0.3, 0.2, -0.05];	// 雲をずらす量。
		private var _offsetSpeedListY:Array = [0.2, 0.1, -0.05, -0.1];
		
		// 立体化関係
		private var _displacementBitmapData:BitmapData;
		private var _displacementMapFilter:DisplacementMapFilter;
		
		// 色変換関係
		private var _paletteBitmapData:BitmapData;
		private var _palette:Array = [];
		private var _nullPalette:Array = [];
		
		// 引き伸ばした画像データ
		private var _scaleChangeBitmapData:BitmapData;
		private var _scaleChangeMatrix:Matrix;
		
		// ちょっとしたカバー
		private var _cover:Sprite;
		
		// その他
		private var _rect:Rectangle = new Rectangle(0, 0, STAGE_W, STAGE_H);
		private var _point:Point = new Point(0, 0);
		private var _rectSmall:Rectangle = new Rectangle(0, 0, _perlinNoiseSizeW, _perlinNoiseSizeH);
		
		public function CloudEffect1()
		{
			addEventListener(Event.ADDED_TO_STAGE, init);	// flexBuilderとの互換性。
		}
		
		private function init(e:Event):void {	// ここから開始
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// SWF設定
			stage.frameRate = 30;
			stage.quality = StageQuality.HIGH;
			
			// 雲模様データを用意する
			_perlinNoiseBitmapData = new BitmapData(_perlinNoiseSizeW, _perlinNoiseSizeH, false);
			for (var i:int = 0; i < _octaves; i++) _offsetList.push(new Point());
			
			// 立体化データを用意する
			_displacementBitmapData = new BitmapData(_perlinNoiseSizeW, _perlinNoiseSizeH, false);
			_displacementMapFilter = new DisplacementMapFilter(null, _point, 0, BitmapDataChannel.BLUE, 0,
									 -120, DisplacementMapFilterMode.CLAMP);
			
			// 色変換データを用意する
			_paletteBitmapData = new BitmapData(STAGE_W, STAGE_H, false);
			createGradation();
			
			// サイズ
			_scaleChangeBitmapData = new BitmapData(STAGE_W, STAGE_H, false);
			_scaleChangeMatrix = new Matrix();
			_scaleChangeMatrix.scale(1/_perlinNoiseSize, 1/_perlinNoiseSize/_H_RATE);
			
			// 白っぽいカバー
			_cover = new Sprite();
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(STAGE_W, STAGE_H, Math.PI/2);
			_cover.graphics.beginGradientFill(GradientType.LINEAR, [0x808080, 0x202020], [1, 1], [128, 255], matrix);
			_cover.graphics.drawRect(0, 0, STAGE_W, STAGE_H);
			_cover.blendMode = BlendMode.OVERLAY;
			
			// 表示
			addChild(new Bitmap(_scaleChangeBitmapData));
			addChild(_cover);
			
			// Stats
			addChild(new Stats());
			
			addEventListener(Event.ENTER_FRAME, frame);
		}
		private function createGradation():void{	// グラデーションを作るよ
			var tmpShape:Shape = new Shape();
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(255, 0);
			var colorList:Array = [0x100010, 0x301020, 0x602030, 0xD08040, 0xFFF080, 0xFFFFF0];
			var alphaList:Array = [1,        1,        1,        1,        1,        1];
			var ratioList:Array = [0,       20,       80,      160,      220,      255];
			tmpShape.graphics.beginGradientFill(GradientType.LINEAR, colorList, alphaList, ratioList, matrix);
			tmpShape.graphics.drawRect(0, 0, 255, 1);
			var tmpBitmap:BitmapData = new BitmapData(255, 1, false);
			tmpBitmap.draw(tmpShape);
			for (var i:int=0; i<256; i++){
				_palette.push(tmpBitmap.getPixel(i, 0));
				_nullPalette.push(0x000000);
			}
		}
		
		private var _colorTransform1:ColorTransform = new ColorTransform(1.3, 1.3, 1.3, 1, 0, 0, 0, 0);
		private var _colorTransform2:ColorTransform = new ColorTransform(0.5, 0.5, 0.5, 1, 100, 100, 100, 0);
		private var _colorTransform3:ColorTransform = new ColorTransform(0.25, 0.25, 0.25, 1, 0, 0, 0, 0);
		private var _colorTransform4:ColorTransform = new ColorTransform(0.25, 0.25, 0.25, 1, -10, -10, -10, 0);
		private var _colorTransform5:ColorTransform = new ColorTransform(1, 1, 1, 1, -1, -1, -1, 0);
		private function frame(event:Event):void{	
			var i:int;
			for (i = 0; i < _octaves; i++){	// 雲模様のオフセットを決める
				Point(_offsetList[i]).x += Number(_offsetSpeedListX[i]);
				Point(_offsetList[i]).y += Number(_offsetSpeedListY[i]);
			}
			var matrix:Matrix = new Matrix();
			// 雲模様を作成
			_perlinNoiseBitmapData.perlinNoise(_cloudSize, _cloudSize, _octaves, _seed, false, true, 0, true, _offsetList);
			// 立体感を出す
			_displacementMapFilter.mapBitmap = _perlinNoiseBitmapData;
			_displacementBitmapData.applyFilter(_perlinNoiseBitmapData, _rectSmall, _point, _displacementMapFilter);
			_displacementBitmapData.draw(_perlinNoiseBitmapData, null, _colorTransform1, BlendMode.HARDLIGHT);
			matrix.scale(1, 0.95);
			_displacementBitmapData.draw(_perlinNoiseBitmapData, matrix, _colorTransform2, BlendMode.SUBTRACT);
			_displacementBitmapData.scroll(0, 20);
			_displacementBitmapData.fillRect(new Rectangle(0, 0, _displacementBitmapData.width, 20), 0x000000)
			_displacementBitmapData.draw(_perlinNoiseBitmapData, null, _colorTransform3, BlendMode.ADD);
			// 光らせる
			matrix.identity();
			for (i = 0; i < 8; i++)
			{
				matrix.translate(-_perlinNoiseSizeW/2, 0);
				matrix.scale(1.03, 1.01);
				matrix.translate(_perlinNoiseSizeW/2, 2);
				_displacementBitmapData.draw(_displacementBitmapData, matrix, _colorTransform4, BlendMode.ADD, null, true);
			}
			_displacementBitmapData.colorTransform(_displacementBitmapData.rect, _colorTransform5);
			// パレットマップで変換
			_paletteBitmapData.paletteMap(_displacementBitmapData, _rectSmall, _point, _palette, _nullPalette, _nullPalette);
			// 引き伸ばす
			_scaleChangeBitmapData.draw(_paletteBitmapData, _scaleChangeMatrix, null, null, null, true);
		}
		
	}
}

Forked