[習作]FireTest
炎の作り方を参考にさせてもらうため、一度DLしたソースをいじいじ。なんでdiffは1mmも参考にならない。
//////////////////////////////////////////////////////////////////////////////
[AS3.0] Fireクラスに挑戦! (1)
http://www.project-nya.jp/modules/weblog/details.php?blog_id=950
//////////////////////////////////////////////////////////////////////////////
/**
* Copyright ug24k8 ( http://wonderfl.net/user/ug24k8 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jE5o
*/
// 炎の作り方を参考にさせてもらうため、一度DLしたソースをいじいじ。なんでdiffは1mmも参考にならない。
// forked from ProjectNya's FireTest
////////////////////////////////////////////////////////////////////////////////
// [AS3.0] Fireクラスに挑戦! (1)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=950
////////////////////////////////////////////////////////////////////////////////
package
{
import adobe.utils.CustomActions;
import flash.display.*;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
[SWF(backgroundColor="#000000", width="340", height="340", frameRate="30")]
public class FireMake extends Sprite {
private const _fireWidth:uint = 50;
private const _fireHeight:uint = 100;
private const _noisyBmpOct:uint = 6; // ノイズ複雑さ
private const _noiseSeed:uint = 10;
private var _noisyBmpData:BitmapData = new BitmapData(_fireWidth + 40, _fireHeight + 40);
private var _noiseOffset:Array = new Array();
private var _noiseOffsetSpeed:Array = new Array();
private var _flareSprite:Sprite;
public function FireMake() {
// テキスト用データ初期化
var text0:TextField = new TextField();
var text1:TextField = new TextField();
var text2:TextField = new TextField();
var textformat:TextFormat = new TextFormat();
textformat.align = TextFormatAlign.CENTER;
text0.defaultTextFormat = textformat;
text1.defaultTextFormat = textformat;
text2.defaultTextFormat = textformat;
// 裏地
var burnBoardShape:Shape = createBurnBoardShape();
burnBoardShape.x = 50;
burnBoardShape.y = 150;
addChild(burnBoardShape);
text0.text = "オリジナル";
text0.x = 50 - text0.width / 2;
text0.y = 10;
text0.textColor = 0xFFFFFF;
addChild(text0);
// マスク
var fireMaskShape:Shape = createFireMaskShape();
fireMaskShape.x = 150;
fireMaskShape.y = 150;
addChild(fireMaskShape);
text1.text = "Mask";
text1.x = 150 - text1.width / 2;
text1.y = 10;
text1.textColor = 0xFFFFFF;
addChild(text1);
// 裏地+マスク
var maskedBurn:Sprite = createMaskedBurnSprite();
maskedBurn.x = 150;
maskedBurn.y = 300;
addChild(maskedBurn);
// フォースマップ用ノイズデータ
var i:int;
for (i = 0; i < _noisyBmpOct; ++i) {
// 配列作成&速度決定
_noiseOffset.push(new Point());
_noiseOffsetSpeed.push(Math.random() * 10 + 0.1);
}
makeNoisyBmpData();
// フォースマップ
var noisyBitmap:Bitmap = new Bitmap(_noisyBmpData);
noisyBitmap.x = 250 - noisyBitmap.width / 2;
noisyBitmap.y = 150 - noisyBitmap.height + 20;
addChild(noisyBitmap);
text2.text = "DisplacementMap";
text2.x = 250 - text2.width / 2;
text2.y = 10;
text2.textColor = 0xFFFFFF;
addChild(text2);
// 裏地+マスク+フォースマップ
_flareSprite = createMaskedBurnSprite();
createFlareSprite(_flareSprite, _noisyBmpData);
_flareSprite.x = 250;
_flareSprite.y = 300;
addChild(_flareSprite);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
// ノイズを動かしてみる
private function onEnterFrame(evt:Event):void {
var i:int;
for (i = 0; i < _noisyBmpOct; ++i) {
// 配列速度適用
_noiseOffset[i].y += _noiseOffsetSpeed[i];
}
makeNoisyBmpData();
createFlareSprite(_flareSprite, _noisyBmpData);
}
// フォースマップ用ノイズデータ作成
private function makeNoisyBmpData():void {
var target:BitmapData = _noisyBmpData;
var fractal:Boolean = true;
var grayscale:Boolean = true;
target.lock();
target.perlinNoise(
target.width / 4, target.height / 4, _noisyBmpOct,
_noiseSeed, false, fractal,
BitmapDataChannel.RED, grayscale,
_noiseOffset);
target.unlock();
}
// 炎スプライト作成
private function createFlareSprite(target:Sprite, noise:BitmapData):void {
var mapfilter:DisplacementMapFilter =
new DisplacementMapFilter(
noise, new Point(),
BitmapDataChannel.RED, BitmapDataChannel.RED,
10, 70,
DisplacementMapFilterMode.CLAMP);
target.filters = [mapfilter];
}
// マスクされた炎板 Sprite 作成
private function createMaskedBurnSprite():Sprite {
var target:Sprite = new Sprite();
var burnBoardShape:Shape = createBurnBoardShape();
var fireMaskShape:Shape = createFireMaskShape();
burnBoardShape.mask = fireMaskShape;
burnBoardShape.cacheAsBitmap = true; // alphaを有効にする為にキャッシュ化 有効
// fireMaskShape.cacheAsBitmap = true; // 生成時にfilterを適用した際に既に 有効に
target.addChild(burnBoardShape);
target.addChild(fireMaskShape);
return target;
}
// 炎マスク Shape 作成
private function createFireMaskShape():Shape {
var target:Shape = new Shape();
var w:Number = _fireWidth;
var h:Number = _fireHeight;
target.graphics.beginFill(0x0000FF);
target.graphics.moveTo(-w*0.5, -h*0.2);
target.graphics.curveTo(-w*0.4, -h, 0, -h);
target.graphics.curveTo(w*0.4, -h, w*0.5, -h*0.2);
target.graphics.curveTo(w*0.5, 0, 0, 0);
target.graphics.curveTo(-w*0.5, 0, -w*0.5, -h*0.2);
target.graphics.endFill();
target.filters = [new BlurFilter(8, 8, 3)]
return target;
}
// 炎板 Shape 作成
private function createBurnBoardShape():Shape {
var target:Shape = new Shape();
var w:uint = _fireWidth + 40;
var h:uint = _fireHeight + 40;
var colors:Array = [0xFF0000, 0x990000, 0xFF9900, 0xFFFF66, 0xFFFFFF, 0xFFFFFF];
var alphas:Array = [1, 1, 1, 1, 1, 1];
var ratios:Array = [30, 80, 127, 150, 200, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(w, h, Math.PI / 2, -w/2, -h+(40/2));
target.graphics.beginGradientFill(
GradientType.LINEAR, colors, alphas, ratios, matrix,
SpreadMethod.PAD, InterpolationMethod.RGB, 0.75);
target.graphics.drawRect(-w/2, -h+(40/2), w, h);
target.graphics.endFill();
return target;
}
}
}