Forcemap Particles
/**
* Copyright takumi0125 ( http://wonderfl.net/user/takumi0125 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xRDe
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
[SWF(backgroundColor = "0xffffff", frameRate = "60")]
public class Main extends Sprite {
private var _particles:Vector.<ParticleItem>; //パーティクルデータ
private var _mainBitmap:Bitmap; //メインのBitmap
private var _mainBitmapData:BitmapData; //メインのBitmapData
private var _forceMap:BitmapData; //forcemap (BitmapData)
private var _forceMapOffset:Array; //forcemapのoffset
private var _forceMapSeed:Number; //forcemapのseed
private var _forceMapUpdateTimer:Timer; //forcemap更新のタイマー
private var _bitmapRect:Rectangle; //ビットマップの範囲
private var _fadeOutColorTransform:ColorTransform; //フェードアウト用のColorTransform
private const _NUM_PARTICLES:uint = 10000; //パーティクルの数
//constructor
public function Main() {
_init();
}
//イニシャライズ
private function _init():void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT
//メインのビットマップ
_mainBitmap = new Bitmap();
addChild(_mainBitmap);
_fadeOutColorTransform = new ColorTransform(1, 1, 1, 1, 1, 1, 1);
//タイマーでフォースマップを1秒ごとに更新
_forceMapOffset = [ new Point(0,0), new Point(0,0) ];
_forceMapUpdateTimer = new Timer(1000);
_forceMapUpdateTimer.addEventListener(TimerEvent.TIMER, _updatePerlinNoise);
_resizeHandler();
//パーティクルデータ生成
_particles = new Vector.<ParticleItem>();
var particle:ParticleItem;
for(var i:uint = 0; i < _NUM_PARTICLES; i++) {
particle = new ParticleItem();
_particles.push(particle);
}
//リサイズ処理
stage.addEventListener(Event.RESIZE, _resizeHandler);
//フレームごとの処理
addEventListener(Event.ENTER_FRAME, _enterFrameHandler);
}
//perlineNoiseを更新
private function _updatePerlinNoise(e:TimerEvent = null):void {
_forceMapOffset[0].x += 3;
_forceMapOffset[1].y += 3;
_forceMapSeed = Math.floor(Math.random() * 0xFFFFFF);
_forceMap.perlinNoise(200, 200, 2, _forceMapSeed, false, true, 6, false, _forceMapOffset);
}
//リサイズ処理
private function _resizeHandler(e:Event = null):void {
_bitmapDataWidth = stage.stageWidth;
_bitmapDataHeight = stage.stageHeight;
_bitmapRect = new Rectangle(0, 0, _bitmapDataWidth, _bitmapDataHeight);
//フォースマップ
if(_forceMap) _forceMap.dispose();
_forceMap = new BitmapData(_bitmapDataWidth, _bitmapDataHeight, false, 0x000000);
_forceMapUpdateTimer.stop();
_forceMapUpdateTimer.reset();
_forceMapUpdateTimer.start();
_updatePerlinNoise();
//メインのビットマップ
if(_mainBitmapData) _mainBitmapData.dispose();
_mainBitmapData = new BitmapData(_bitmapDataWidth, _bitmapDataHeight, false, 0xffffffff);
_mainBitmap.bitmapData = _mainBitmapData;
}
//フレームごとの処理
private function _enterFrameHandler(e:Event):void {
_mainBitmapData.colorTransform(_bitmapRect, _fadeOutColorTransform);
var particle:ParticleItem;
_mainBitmapData.lock();
for(var i:uint = 0; i < _NUM_PARTICLES; i++) {
particle = _particles[i];
//フォースマップの色抽出
particle.updateParams(_forceMap.getPixel(particle.x, particle.y));
//描画
_mainBitmapData.setPixel(particle.x, particle.y, 0xaacf53);
}
_mainBitmapData.unlock();
}
}
}
var _bitmapDataWidth:Number; //ビットマップの横幅
var _bitmapDataHeight:Number; //ビットマップの縦幅
//パーティクル
class ParticleItem {
private var _x:Number, _y:Number; //位置
private var _vx:Number, _vy:Number; //速度
private var _ax:Number, _ay:Number; //加速度
//constructor
public function ParticleItem() {
_vx = _vy = _ax = _ay = 0;
_x = Math.random() * _bitmapDataWidth;
_y = Math.random() * _bitmapDataHeight;
}
//位置、加速度、速度更新
public function updateParams(color:uint):void {
_ax += ((color & 0xff) - 0x80 ) * .0005;
_ay += ((color >> 8 & 0xff) - 0x80 ) * .0005;
_vx += _ax;
_vy += _ay;
_x += _vx;
_y += _vy;
_ax *= .96;
_ay *= .96;
_vx *= .92;
_vy *= .92;
(_x > _bitmapDataWidth)? _x = 0: (_x < 0)? _x = _bitmapDataWidth: 0;
(_y > _bitmapDataHeight)? _y = 0: (_y < 0)? _y = _bitmapDataHeight: 0;
}
//_xを取得
public function get x():Number {
return _x;
}
//_yを取得
public function get y():Number {
return _y;
}
//_vxを取得
public function get vx():Number {
return _vx;
}
//_vyを取得
public function get vy():Number {
return _vy;
}
}