[Away3D] Explosion Effect 2 (爆発エフェクト2)
copyright (c) www.romatica.com
@author itoz ( http://www.romatica.com/ )
Away3D Explosion Effect2
/**
* Copyright romatica ( http://wonderfl.net/user/romatica )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6XMa
*/
/**
* copyright (c) www.romatica.com
* @author itoz ( http://www.romatica.com/ )
*/
package
{
import flash.display.BitmapData;
import away3d.containers.View3D;
import away3d.filters.BloomFilter3D;
import away3d.primitives.WireframeSphere;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.getTimer;
[SWF(backgroundColor="#000000", frameRate="60", width="465", height="465")]
/**
* Away3D Explosion Effect2
*/
public class Wonderfl_ExplosionEffect2 extends View3D
{
private static const LOOKPOINT : Vector3D = new Vector3D(0, 0, 0);
private var _explosion : Explosion;
private var _inited : Boolean;
private var _capture : Bitmap;
private var _tf : TextField;
public function Wonderfl_ExplosionEffect2()
{
super();
if (stage) _initialize(null);
else addEventListener(Event.ADDED_TO_STAGE, _initialize);
}
private function _initialize(event : Event) : void
{
removeEventListener(Event.ADDED_TO_STAGE, _initialize);
// ★wonderfl capture
Wonderfl.disable_capture();
//_capture = addChild(new Bitmap(new BitmapData(465, 465, false, 0x000000))) as Bitmap ;
antiAlias = 4;
createObject();
addEventListener(Event.ENTER_FRAME, onUpdate);
camera.x = 200;
camera.y = 00;
camera.z = -200;
addEventListener(MouseEvent.CLICK, onClick);
for (var i : int = 0; i < 64; i++) {
var sphere : WireframeSphere = scene.addChild(new WireframeSphere(1, 2, 3)) as WireframeSphere;
sphere.x = Math.random() * 1024 - 512;
sphere.y = Math.random() * 1024 - 512;
sphere.z = Math.random() * 1024 - 512;
}
_tf = addChild(new TextField()) as TextField;
_tf.defaultTextFormat = new TextFormat(null, 16, 0xffffff);
_tf.autoSize = TextFieldAutoSize.LEFT;
_tf.text = "CLICK TO STAGE!";
_tf.mouseEnabled = false;
_tf.x = stage.stageWidth * 0.5 - _tf.width * 0.5;
_tf.y = stage.stageHeight * 0.9 - _tf.height * 0.5;
}
private function onClick(event : MouseEvent) : void
{
_explosion.doEffect();
}
private function createObject() : void
{
//----------------------------------
// create objects
//----------------------------------
_explosion = scene.addChild(new Explosion()) as Explosion;
}
private function onUpdate(event : Event) : void
{
if (!_inited) {
_inited = true;
filters3d = [new BloomFilter3D(16, 16, 0.2)];
}
var t : Number = getTimer();
camera.x = Math.cos(t / 2048) * 512;
camera.y = Math.sin(t / 2048) * 256;
camera.z = 400;
camera.lookAt(LOOKPOINT);
render();
_tf.alpha = (_tf.alpha ==1) ? 0.7 : 1;
// wonderfl capture
if (_capture) renderer.queueSnapshot(_capture.bitmapData);
}
}
}
import a24.tween.Ease24;
import a24.tween.Tween24;
import away3d.containers.ObjectContainer3D;
import away3d.entities.Mesh;
import away3d.entities.Sprite3D;
import away3d.lights.PointLight;
import away3d.materials.TextureMaterial;
import away3d.materials.lightpickers.LightPickerBase;
import away3d.materials.lightpickers.StaticLightPicker;
import away3d.primitives.PlaneGeometry;
import away3d.textures.BitmapTexture;
import frocessing.color.ColorHSV;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.BlendMode;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Shape;
import flash.display.SpreadMethod;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.utils.Dictionary;
//--------------------------------------------------------------------------
//
// Explosion
//
// --------------------------------------------------------------------------
class Explosion extends ObjectContainer3D
{
private static const COLOR : uint=0xffe76f;
private var lines : Array;
private var ring : ExplosionRing;
private var smoke : ExplosionSmoke;
private var lightPicker : StaticLightPicker;
private var hsv : ColorHSV;
private var light : PointLight;
public function Explosion()
{
super();
visible = false;
var w : int = 32;
var h : int = 128;
hsv = new ColorHSV();
hsv.value = COLOR;
light = new PointLight();
light.ambientColor = hsv.value;
light.ambient = 1;
light.specular = 1;
light.diffuse = 1;
lightPicker = new StaticLightPicker([light]);
lines = [];
var max : int = 32;
for (var i : int = 0; i < max; i++) {
var line : ExplosionLine = addChild(new ExplosionLine(w, h, lightPicker)) as ExplosionLine;
line.scale(Math.random() * 0.5 + 0.5);
lines.push(line);
}
ring = addChild(new ExplosionRing(480, lightPicker)) as ExplosionRing;
smoke = addChild(new ExplosionSmoke(360, lightPicker)) as ExplosionSmoke;
}
public function doEffect() : void
{
visible = true;
for (var i : int = 0; i < lines.length; i++) {
var line : ExplosionLine = lines[i] as ExplosionLine;
if (line) line.doEffect();
}
ring.doEffect();
smoke.doEffect();
////
// Tween24.tween(hsv,1.25,Ease24._1_SineOut,{"h":360,"s":0,"v":0})
// .onUpdate(onColorUpdate)
// .onComplete(onColorComplete)
// .play();
}
//
// private function onColorUpdate() : void
// {
// light.ambientColor = hsv.value;
// }
//
// private function onColorComplete() : void
// {
// visible = false;
// hsv.value = COLOR;
// light.ambientColor = hsv.value;
// }
}
// --------------------------------------------------------------------------
//
// Exprosion Line
//
// --------------------------------------------------------------------------
class ExplosionLine extends ObjectContainer3D
{
private static var MAX_ALPHA : Number = 0.8;
private var _lightPicker : LightPickerBase;
private var line : Mesh;
private var w : Number;
private var h : Number;
private var mat : TextureMaterial;
public function ExplosionLine(wid : Number = 32, hei : Number = 128, lightPicker : LightPickerBase = null)
{
super();
if (lightPicker) _lightPicker = lightPicker;
visible = false;
MAX_ALPHA = Math.random() * 0.25 + 0.75;
w = wid || 32;
h = hei || 128;
var sp : Shape = new Shape();
var startH : Number = 0;
var endH : Number = h * 0.9;
var leng : Number = endH - startH;
var xx : Number = 32 >> 1;
var g : Graphics = sp.graphics;
g.moveTo(xx, 128 * 0.1);
var max : int = 32;
for (var i : int = 0; i < max; i++) {
var yy : Number = leng / max * i + startH;
g.lineStyle(0.1 * i * (i * 0.05), 0xffffff, 0.1 * i);
g.lineTo(xx, yy);
}
g.endFill();
var bmd : BitmapData = new BitmapData(w, h, true, 0x0);
bmd.draw(sp);
mat = new TextureMaterial(new BitmapTexture(bmd));
mat.alphaBlending = true;
mat.bothSides = true;
mat.specular = 1;
if (_lightPicker) mat.lightPicker = _lightPicker;
var mat3d : Matrix3D = new Matrix3D();
mat3d.appendTranslation(0, 0, -h >> 1);
var geo : PlaneGeometry = new PlaneGeometry(w, h);
geo.applyTransformation(mat3d);
line = addChild(new Mesh(geo, mat)) as Mesh;
line.rotationX = 90;
sp = null;
resetParams();
}
private function resetParams() : void
{
visible = false;
line.y = 0;
line.rotationY = 0;
line.scaleX = 0;
line.scaleY = 0;
line.scaleZ = 0;
mat.alpha = 1;
}
public function doEffect() : void
{
// ランダムな方向
doRandomRotation();
// パラメータリセット
resetParams();
//
var t : Number = 0.35 + Math.random() * 0.45;
var dt : Number = t * 0.7;
var yy : Number = Math.random() * h * 0.5 + h * 0.5 ;
var sz : Number = 0.5 * Math.random() + 1;
Tween24.parallel(
Tween24.tween(mat, t - dt).delay(dt).alpha(0)
, Tween24.tween(line, t, Ease24._3_CubicInOut).y(yy).scaleX(1).scaleY(1).scaleZ(sz).rotationY(360*(Math.random()*4+2))
).onComplete(onEffectComplete).play();
visible = true;
}
private function doRandomRotation() : void
{
this.rotationX = Math.random() * 360;
this.rotationY = Math.random() * 360;
this.rotationZ = Math.random() * 360;
}
private function onEffectComplete() : void
{
// パラメータリセット
resetParams();
}
}
// --------------------------------------------------------------------------
//
// Exprosion Ring
//
// --------------------------------------------------------------------------
class ExplosionRing extends ObjectContainer3D
{
public static var explosionBitmapData : BitmapData;
private var plane : Mesh;
private var isPlay : Boolean;
private var _size : int;
private var _lightPicker : LightPickerBase;
private var _loader : Loader;
public function ExplosionRing(size : int = 512, lightPicker : LightPickerBase = null)
{
super();
_lightPicker = lightPicker;
_size = size || 512;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete_Handler);
_loader.load(new URLRequest("http://www.romatica.com/dev/wonderfl/explosion/ring.png"), new LoaderContext(true));
}
private function loadComplete_Handler(event : Event) : void
{
explosionBitmapData = ((event.target as LoaderInfo).content as Bitmap).bitmapData;
createObject();
}
private function createObject() : void
{
if (explosionBitmapData) {
var material : TextureMaterial = new TextureMaterial(new BitmapTexture(explosionBitmapData));
material.alphaBlending = true;
material.bothSides = true;
material.specular = 1;
if (_lightPicker) material.lightPicker = _lightPicker;
var planeGeo : PlaneGeometry = new PlaneGeometry(_size, _size, 16, 16);
plane = new Mesh(planeGeo, material);
plane.scaleX = plane.scaleY = plane.scaleZ = 0;
addChild(plane);
}
}
public function doEffect() : void
{
if (!plane) return ;
if (isPlay) return;
isPlay = true;
plane.rotateTo(Math.random() * 360, Math.random() * 360, Math.random() * 360);
plane.scaleX = plane.scaleY = plane.scaleZ = 0;
plane.rotationY = 0;
var mat : TextureMaterial = plane.material as TextureMaterial;
mat.alpha = 0.4;
var scale : Number = Math.random() * 0.3 + 0.9;
Tween24.serial(
Tween24.parallel(
Tween24.tween(plane, 0.3, Ease24._1_SineOut).scaleX(1).scaleY(1).scaleZ(1)
, Tween24.tween(mat, 0.3).alpha(0.5))
, Tween24.parallel(
Tween24.tween(plane, 0.25, Ease24._2_QuadIn).scaleX(scale).scaleY(scale).scaleZ(scale)
,Tween24.tween(mat, 0.25, Ease24._2_QuadIn).alpha(0)
)
, Tween24.func(function() : void{isPlay = false;})
).play();
}
}
// --------------------------------------------------------------------------
//
// Exprosion Smoke
//
// --------------------------------------------------------------------------
class ExplosionSmoke extends ObjectContainer3D
{
public var smokeAlpha : Number = 1;
private static const RECT : Rectangle = new Rectangle(0, 0, 256, 256);
private static const SPEED : Number = -1.5;
private static const SEED : Number = Math.random();
private static const P : Point = new Point();
private var gColor : Array = [0x000000, 0x000000];
private var gAlpha : Array = [0, 255];
private var noizBmd : BitmapData;
private var bmd : BitmapData;
private var offsets : Array;
private var gDic : Dictionary;
private var smoke : Sprite3D;
private var material : TextureMaterial;
private var noizeSize:int = 256;
private var _lightPicker : LightPickerBase;
private var _size : int;
public function ExplosionSmoke(size : int = 256, lightPicker : LightPickerBase = null)
{
super();
visible = false;
_lightPicker = lightPicker;
_size = size || 256;
// ----------------------------------
// perlin noize
// ----------------------------------
offsets = [new Point(), new Point()];
noizBmd = new BitmapData(noizeSize, noizeSize, false);
// ----------------------------------
// bitmap
// ----------------------------------
bmd = new BitmapData(noizeSize, noizeSize, true, 0xffffffff);
material = new TextureMaterial(new BitmapTexture(bmd));
material.alphaBlending = true;
if (_lightPicker) material.lightPicker = _lightPicker;
smoke = addChild(new Sprite3D(material, _size, _size)) as Sprite3D;
}
public function doEffect() : void
{
if (visible ) return ;
visible = true;
smokeAlpha = 0.1;
var fadeOutTime : Number =0.6;// 0.4 * Math.random() + 0.3;
scaleX = scaleY = scaleZ = 0;
Tween24.serial(
Tween24.tween(this, fadeOutTime*0.2, Ease24._1_SineInOut, {"smokeAlpha":0.9,"scaleX":1,"scaleY":1,"scaleZ":1})
,Tween24.tween(this, fadeOutTime*0.8, Ease24._2_QuadIn, {"smokeAlpha":0})
)
.onUpdate(onUpdate)
.onComplete(function():void{ visible = false;})
.play();
}
private function onUpdate() : void
{
var i : int;
var max : int = offsets.length;
for (i = 0; i < max; i++) {
var p : Point = offsets[i] as Point;
var direc : int = (i % 2 == 0) ? 1 : -1;
p.x += (SPEED * (i + 1) * direc) >> 1;
p.y += (SPEED * (i + 1) * direc);
}
noizBmd.perlinNoise(noizeSize>>2, noizeSize>>2, offsets.length, SEED, false, true, BitmapDataChannel.ALPHA, true, offsets);
noizBmd.draw(getGarad(smokeAlpha), null, null, BlendMode.ALPHA);
noizBmd.draw(noizBmd, null, null, BlendMode.ADD);
bmd.fillRect(RECT, 0xffffffff);
bmd.copyChannel(noizBmd, RECT, P, BitmapDataChannel.RED, BitmapDataChannel.ALPHA);
if (material) material.texture = new BitmapTexture(bmd);
}
/**
* circle gradation
*/
private function getGarad(smokeAlpha : Number) : Shape
{
if (smokeAlpha > 1 ) smokeAlpha = 1;
if (smokeAlpha < 0 ) smokeAlpha = 0;
var smokeKey : String = int(smokeAlpha * 100).toString();
if (!gDic) gDic = new Dictionary();
if (!gDic[smokeKey]) {
var grad : Shape = new Shape();
var gradMrx : Matrix = new Matrix();
gradMrx.createGradientBox(256, 256, Math.PI / 2, 0, 0);
var g : Graphics = grad.graphics;
g.beginGradientFill(GradientType.RADIAL, gColor, [smokeAlpha, 0], gAlpha, gradMrx, SpreadMethod.PAD);
g.drawRect(0, 0, 256, 256);
gDic[smokeKey] = grad;
}
return gDic[smokeKey] ;
}
}