パーティクルエフェクト
/**
* Copyright yun ( http://wonderfl.net/user/yun )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xIMk
*/
// forked from yun's 残像エフェクトつきサウンドビジュアライザ
// forked from yun's サウンドビジュアライザ
// forked from yun's カメラの動きにイージングを付ける
// forked from yun's カメラの動きを指定
// forked from yun's 3Dオブジェクトに動きを付ける
// forked from yun's シンプルな3Dオブジェクト
package {
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
import flash.events.*;
import flash.media.*;
import flash.net.*;
import flash.utils.*;
import org.libspark.betweenas3.*;
import org.libspark.betweenas3.easing.*;
import org.libspark.betweenas3.tweens.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.utils.*;
import org.papervision3d.materials.special.ParticleMaterial;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.objects.special.ParticleField;
import org.papervision3d.view.*;
import org.papervision3d.view.layer.*;
import org.papervision3d.core.effects.*;
import org.papervision3d.core.effects.utils.*;
public class Sample extends BasicView {
private const PIXEL_NUM :int = 22;
private const MAX_RADIUS :int = 20000;
private const PLANE_SIZE :int = 500;
private const PLANE_MARGIN :int = 0;
private var pixelArr :Array = [];
private var dmyObjs :Array = [];
private var dmyPixels :Array = [];
private var index :int = 0;
private var soundChannel:SoundChannel;
private var sphere:Sphere;
private var bfx:BitmapEffectLayer;
// パーティクル形状を配列として格納
static private const IMAGE_LIST:Array = [
[
[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0]
],
[
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1],
[0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0]
],
[
[0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0],
[0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0],
[0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0],
[0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0],
[0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1],
[1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1],
[1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1],
[1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0],
[0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0]
]
];
public function Sample():void {
viewport.opaqueBackground = 0x000000;
// エフェクトレイヤーを追加
bfx = new BitmapEffectLayer( viewport, 465, 465 );
bfx.addEffect( new BitmapLayerEffect( new BlurFilter( 16, 16, 5 ) ) );
bfx.drawCommand = new BitmapDrawCommand( null, new ColorTransform( 1, 1, 1, 0.15 ), BlendMode.ADD );
bfx.clippingPoint = new Point( 0, 0 );
viewport.containerSprite.addLayer( bfx );
// 4秒ごとに形状が変化するようにタイマーをセット
var timer:Timer = new Timer( 4000 );
timer.addEventListener( TimerEvent.TIMER, trans );
timer.start();
// 初期化
init();
/*
// 球体を作成
var material1:WireframeMaterial = new WireframeMaterial( 0xFF0000 );
var material2:WireframeMaterial = new WireframeMaterial( 0x00CCFF );
sphere = new Sphere( material1, 800, 20, 20 );
sphere.x = 600;
scene.addChild( spher1 );
// エフェクトレイヤーに追加
bfx.addDisplayObject3D( sphere );
// 音楽読み込み
var sound:Sound = new Sound( new URLRequest( "http://mutast.heteml.jp/works/music/music.mp3" ) );
soundChannel = sound.play();
*/
// モーションを100ミリ秒遅らせて開始
setTimeout( trans, 100 );
// レンダリング
startRendering();
addEventListener( Event.ENTER_FRAME, loop );
}
// 初期化
private function init():void {
// 外枠の長方形
var wire:WireframeMaterial = new WireframeMaterial( 0x333333 );
wire.opposite = true;
var cube:Cube = new Cube(
new MaterialsList( { all:wire } ),
MAX_RADIUS, MAX_RADIUS, MAX_RADIUS,
5, 5, 5 );
scene.addChild( cube );
var stars:ParticleField = new ParticleField( new ParticleMaterial( 0xFFFFFF, 2, 0 ), 1000, 100, MAX_RADIUS *3, MAX_RADIUS *3, MAX_RADIUS *3 );
scene.addChild( stars );
// パーティクルを生成
var material:ColorMaterial = new ColorMaterial( 0x00CCFF );
material.doubleSided = true;
pixelArr = [];
for ( var i:int = 0; i < PIXEL_NUM; i++ ) {
pixelArr[i] = [];
for ( var j:int = 0; j < PIXEL_NUM; j++ ) {
// Planeインスタンスを作成
var o:Plane = new Plane( material, PLANE_SIZE, PLANE_SIZE );
scene.addChild( o );
pixelArr[i][j] = o;
bfx.addDisplayObject3D( o );
// 座標
o.x = ( +i - PIXEL_NUM / 2 ) * ( PLANE_SIZE + PLANE_MARGIN );
o.y = ( +j - PIXEL_NUM / 2 ) * ( PLANE_SIZE + PLANE_MARGIN );
}
}
// ダミーのピクセルを生成
dmyPixels[k] = [];
for ( var k:int = 0; k < IMAGE_LIST.length; k++ ) {
dmyObjs[k] = new DisplayObject3D();
dmyObjs[k].x = MAX_RADIUS * ( Math.random() - 0.5 );
dmyObjs[k].y = MAX_RADIUS * ( Math.random() - 0.5 );
dmyObjs[k].z = MAX_RADIUS * ( Math.random() - 0.5 );
scene.addChild( dmyObjs[k] );
dmyPixels[k] = [];
for ( i = 0; i < PIXEL_NUM; i++ ) {
dmyPixels[k][i] = [];
for ( j = 0; j < PIXEL_NUM; j++ ) {
dmyPixels[k][i][j] = new DisplayObject3D();
//dmyPixels[k][i][j] = new Plane( new WireframeMaterial(), PLANE_SIZE, PLANE_SIZE );
dmyPixels[k][i][j].x = ( +i - PIXEL_NUM / 2 ) * ( PLANE_SIZE + PLANE_MARGIN );
dmyPixels[k][i][j].y = ( -j + PIXEL_NUM / 2 ) * ( PLANE_SIZE + PLANE_MARGIN );
dmyObjs[k].addChild( dmyPixels[k][i][j] );
}
}
}
}
// 4秒ごとに呼び出されるタイマーイベント
private function trans( e:TimerEvent = null ):void {
// 形状のインデックス番号を更新
index ++;
if ( index == IMAGE_LIST.length ) index = 0;
// 各パーティクルに対してトゥイーンを設定
for ( var i:int = 0; i < PIXEL_NUM; i++ ) {
for ( var j:int = 0; j < PIXEL_NUM; j++ ) {
// パーティクル
var p:DisplayObject3D = pixelArr[i][j];
// ダミーオブジェクト
var d:DisplayObject3D = dmyPixels[index][j][i];
// パーティクルのスケール値
var s:Object = IMAGE_LIST[index][i][j];
// BetweenAS3でトゥイーン
BetweenAS3.delay(
BetweenAS3.bezier( p,
{
x:d.sceneX,
y:d.sceneY,
z:d.sceneZ,
scale:s
},
null,
{
x:MAX_RADIUS * ( Math.random() - 0.5 ),
y:MAX_RADIUS * ( Math.random() - 0.5 ),
z:MAX_RADIUS * ( Math.random() - 0.5 )
},
2 + Math.random(),
Quart.easeInOut),
Math.random() * 1
).play();
}
}
}
private function loop( e:Event ):void {
/*
// 音量取得
var volume:Number = ( soundChannel.leftPeak + soundChannel.rightPeak ) / 2;
// 球体のスケールを制御
sphere.scale -= 0.02;
sphere.scale = Math.max( volume, sphere1.scale );
// 球面の回転を制御
sphere.rotationX += soundChannel.leftPeak * 5;
sphere.rotationY += soundChannel.rightPeak * 5;
*/
// カメラの位置を変更
var rateX:Number = mouseX / stage.stageWidth;
var targetX:Number = -50000 * ( rateX - 0.5 );
camera.x += ( targetX - camera.x ) * 0.2;
var rateY:Number = mouseY / stage.stageHeight;
var targetY:Number = 50000 * ( rateY - 0.5 );
camera.y += ( targetY - camera.y ) * 0.2;
camera.z = -MAX_RADIUS;
}
}
}