📄 bitmapfireeffect.as
字号:
/**
* ...
* @author Default
* @version 0.1
*/
package org.papervision3d.core.effects {
import flash.display.Sprite;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import org.papervision3d.core.layers.*;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.filters.ColorMatrixFilter;
import flash.filters.BlurFilter;
import flash.filters.DisplacementMapFilter;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.DisplayObject;
public class BitmapFireEffect extends AbstractEffect{
private var layer:BitmapEffectLayer;
private var _fadeRate:Number=0.4;
private var _distortionScale:Number=0.4;
private var _distortion:Number=0.5;
private var _flameHeight:Number=0.3;
private var _flameSpread:Number=0.3;
private var _blueFlame:Boolean = false;
private var _smoke:Number = 0;
// private properties:
// display elements:
private var displayBmp:BitmapData;
private var scratchBmp:BitmapData;
private var perlinBmp:BitmapData;
// geom:
private var mtx:Matrix;
private var pnt:Point;
private var drawColorTransform:ColorTransform;
// filters:
private var fireCMF:ColorMatrixFilter;
private var dispMapF:DisplacementMapFilter;
private var blurF:BlurFilter;
// other
private var endCount:Number;
private var bmpsValid:Boolean=false;
private var perlinValid:Boolean=false;
private var filtersValid:Boolean=false;
private var _target:DisplayObject;
public function BitmapFireEffect(r:Number = 1, g:Number = 1, b:Number = 1, a:Number= 1){
mtx = new Matrix();
pnt = new Point();
}
public override function attachEffect(layer:EffectLayer):void{
this.layer = BitmapEffectLayer(layer);
target = layer.drawLayer;
}
public override function postRender():void{
doFire();
//layer.canvas.applyFilter(layer.canvas, layer.canvas.rect, new Point(), fade);
}
public function set width(value:Number):void {
//layer.canvas.width;
}
public function get width():Number {
return layer.canvas.width;
}
public function set height(value:Number):void {
;
}
public function get height():Number {
return layer.canvas.height;
}
[Inspectable(defaultValue=0.4,name='fadeRate (0-1)')]
/**
* Sets the rate that flames fade as they move up. 0 is slowest, 1 is fastest.
*
* @default 0.4
*/
public function set fadeRate(value:Number):void {
filtersValid &&= (value == _fadeRate);
_fadeRate = value;
}
public function get fadeRate():Number {
return _fadeRate;
}
[Inspectable(defaultValue=0.4,name='distortionScale (0-1)')]
/**
* Sets the scale of flame distortion. 0.1 is tiny and chaotic, 1 is large and smooth.
*
* @default 0.4
*/
public function set distortionScale(value:Number):void {
perlinValid &&= (value == _distortionScale);
_distortionScale = value;
}
public function get distortionScale():Number {
return _distortionScale;
}
[Inspectable(defaultValue=0.4,name='distortion (0-1)')]
/**
* Sets the amount of distortion. 0.1 is little, 1 is chaotic.
*
* @default 0.4
*/
public function set distortion(value:Number):void {
filtersValid &&= (value == _fadeRate);
_distortion = value;
}
public function get distortion():Number {
return _distortion;
}
[Inspectable(defaultValue=0.3,name='flameHeight (0-1)')]
/**
* Sets the how high the flame will burn. 0 is zero gravity, 1 is a bonfire.
*
* @default 0.3
*/
public function set flameHeight(value:Number):void {
perlinValid &&= (value == _flameHeight);
_flameHeight = value;
}
public function get flameHeight():Number {
return _flameHeight;
}
[Inspectable(defaultValue=0.3,name='flameSpread (0-1)')]
/**
* Sets the how much the fire will spread out around the target. 0 is no spread, 1 is a lot.
*
* @default 0.3
*/
public function set flameSpread(value:Number):void {
filtersValid &&= (value == _flameSpread);
_flameSpread = value;
}
public function get flameSpread():Number {
return _flameSpread;
}
[Inspectable(defaultValue=false,name='blueFlame')]
/**
* Indicates whether it should use a blue or red flame.
*
* @default false
*/
public function set blueFlame(value:Boolean):void {
filtersValid &&= (value == _blueFlame);
_blueFlame = value;
}
public function get blueFlame():Boolean {
return _blueFlame;
}
[Inspectable(defaultValue=0,name='smoke (0-1)')]
/**
* Sets the amount of smoke. 0 little, 1 lots.
*
* @default 0
*/
public function set smoke(value:Number):void {
filtersValid &&= (value == _smoke);
_smoke = value;
}
public function get smoke():Number {
return _smoke;
}
[Inspectable(defaultValue='',name='target')]
/**
* Sets the amount of smoke. 0 little, 1 lots.
*
* @default
*/
public function set targetName(value:String):void {
}
/**
* Defines the shape of the fire. The fire will burn upwards, so it should be near the bottom, and centered in the FireFX component.
*
* @default
*/
public function set target(value:DisplayObject):void {
_target = value;
clear();
}
public function get target():DisplayObject {
return _target;
}
/**
* Clears the fire.
*/
public function clear():void {
if (displayBmp) {
displayBmp.fillRect(displayBmp.rect,0);
}
}
public function stopFire():void {
// let the fire burn down for 20 frames:
if (endCount == 0) { endCount = 20; }
}
private function updateBitmaps():void {
if (displayBmp) {
displayBmp.dispose();
displayBmp = null;
scratchBmp.dispose();
scratchBmp = null;
perlinBmp.dispose();
perlinBmp = null;
}
displayBmp = layer.canvas;
scratchBmp = displayBmp.clone();
perlinBmp = new BitmapData(width*3, height*3, false, 0);
updatePerlin();
updateFilters();
bmpsValid = true;
}
private function updatePerlin():void {
perlinBmp.perlinNoise(30*_distortionScale,20*_distortionScale,1,-Math.random()*1000|0,false,true,1|2,false);
perlinBmp.colorTransform(perlinBmp.rect,new ColorTransform(1, 1-_flameHeight*0.5 ,1,1,0,0,0,0));
perlinValid = true;
}
private function updateFilters():void {
if (_blueFlame) {
fireCMF = new ColorMatrixFilter([0.8-0.55*_fadeRate,0,0,0,0,
0,0.93-0.48*_fadeRate,0,0,0,
0,0.1,0.96-0.35*_fadeRate,0,0,
0,0.1,0,1,-25+_smoke*24]);
drawColorTransform = new ColorTransform(0,0,0,1,210,240,255,0);
} else {
fireCMF = new ColorMatrixFilter([0.96-0.35*_fadeRate,0.1,0,0,-1,
0,0.9-0.45*_fadeRate,0,0,0,
0,0,0.8-0.55*_fadeRate,0,0,
0,0.1,0,1,-25+_smoke*24]);
drawColorTransform = new ColorTransform(0,0,0,1,255,255,210,0);
}
dispMapF = new DisplacementMapFilter(perlinBmp,pnt,1,2,14*_distortion,-30,"clamp");
blurF = new BlurFilter(32*_flameSpread,32*_flameSpread,1);
filtersValid = true;
}
private function startFire():void {
endCount = 0;
}
private function doFire():void {
if (_target == null) { return; }
if (!bmpsValid) { updateBitmaps(); }
if (!perlinValid) { updatePerlin(); }
if (!filtersValid) { updateFilters(); }
if (endCount == 0) {
var drawMtx:Matrix = _target.transform.matrix;
scratchBmp.fillRect(scratchBmp.rect,0);
drawColorTransform.alphaOffset = -Math.random()*200|0;
scratchBmp.draw(_target,drawMtx,drawColorTransform,"add");
scratchBmp.applyFilter(scratchBmp,scratchBmp.rect,pnt,blurF);
displayBmp.draw(scratchBmp,mtx,null,"add");
}
dispMapF.mapPoint = new Point( -Math.random()*(perlinBmp.width-displayBmp.width)|0, -Math.random()*(perlinBmp.height-displayBmp.height)|0 );
displayBmp.applyFilter(displayBmp,displayBmp.rect,pnt,dispMapF);
displayBmp.applyFilter(displayBmp,displayBmp.rect,pnt,fireCMF);
//if (endCount != 0 && --endCount == 0) {
// removeEventListener(Event.ENTER_FRAME,doFire);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -