Metaball with PerlinNoise
/**
* Copyright linktale ( http://wonderfl.net/user/linktale )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1FJF
*/
/*
元はこちら
http://wonderfl.net/c/lsVb
マウスダウンした状態でマウスを動かすと移動します。
http://linktale.net/
*/
package {
//import com.flashdynamix.utils.SWFProfiler;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
[SWF(backgroundColor="0xffffff", frameRate="40")]
public class Trick extends Sprite {
//Image
private var perlinOfset:Array = [new Point(0, 0), new Point(0, 0)];
private var _blue:BlurFilter;
//メタボールの数
private var _numBlobs:uint = 4;
//メタボールの初期ポジション
private var _blogPx:Array = new Array(20 ,20 , 90, 90);
private var _blogPy:Array = new Array(60, 80, 100, 120);
//メタボールの速度
private var _blogDx:Array = new Array(1, 1, -1, -1);
private var _blogDy:Array = new Array(-1, -1, -1, -1);
//ビットマップ
private var _bmpData1:BitmapData;
private var _bmpData2:BitmapData;
//各ピクセルの色の関係値
private var _vx:Array = new Array();
private var _vy:Array = new Array();
//Drag
private var _downFlg:Boolean = false;
public function Trick():void {
//SWFProfiler.init(stage, this);
//Wonderfl.capture_delay(8);
Wonderfl.disable_capture();
init();
}
private function init():void {
//処理速度を抑えるため
scaleX = scaleY = 3;
//ブラー
_blue = new BlurFilter(10, 10);
//ビットマップ配置
_bmpData1 = new BitmapData(155, 155);
var bitmap1:Bitmap = new Bitmap(_bmpData1);
addChild(bitmap1);
_bmpData2 = _bmpData1.clone();
var bitmap2:Bitmap = new Bitmap(_bmpData2);
addChild(bitmap2);
bitmap2.blendMode = BlendMode.OVERLAY;
//描画
addEventListener(Event.ENTER_FRAME, draw);
//マウス
stage.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
_downFlg = true;
});
stage.addEventListener(MouseEvent.MOUSE_UP, function():void {
_downFlg = false;
});
}
private function draw(e:Event = null):void {
var x:uint, y:uint, i:uint;
var color:uint, r:uint, g:uint, b:uint;
//perlinNoise
_bmpData1.perlinNoise(24, 24, 2, 1000, true, true, 7, false, perlinOfset);
perlinOfset[0].x += 1;
perlinOfset[0].y += 1;
for (i = 0; i < _numBlobs; ++i) {
//速度追加
if(_downFlg){
_blogDx[i] += (int)(stage.stageWidth / 2 - stage.mouseX) * 0.0001;
_blogDy[i] += (int)(stage.stageHeight / 2 - stage.mouseY) * 0.0001;
}
_blogPx[i] += _blogDx[i];
_blogPy[i] += _blogDy[i];
//跳ね返り時の処理
if (_blogPx[i] < 0) {
_blogDx[i] = Math.random();
}
if (_blogPx[i] > _bmpData1.width) {
_blogDx[i] = -Math.random();
}
if (_blogPy[i] < 0) {
_blogDy[i] = Math.random();
}
if (_blogPy[i] > _bmpData1.height) {
_blogDy[i]=-Math.random();
}
//各ピクセルとビットマップのX位置との差の累乗 - 色の係数
_vx[i] = new Array();
for (x = 0; x < _bmpData1.width; x++) {
_vx[i][x] = int(Math.pow(_blogPx[i] - x, 2));
}
//各ピクセルとビットマップのY位置との差の累乗 - 色の係数
_vy[i] = new Array();
for (y = 0; y < _bmpData1.height; y++) {
_vy[i][y] = int(Math.pow(_blogPy[i] - y, 2));
}
}
_bmpData1.lock();
_bmpData2.lock();
for (y = 0; y < _bmpData1.height; y++) {
for (x = 0; x < _bmpData1.width; x++) {
var m:int = 1;
for (i = 0; i < _numBlobs; i++ ) {
//メタボボールの色係数
m += (60000 * (i + 2) * 2) / (_vy[i][y] + _vx[i][x] + 1);
}
//各ピクセルの色を設定
r = Math.min(255, (m + y));
g = Math.min(255, (m + x));
b = Math.min(255, (x + m + y) / 2);
color = r << 16 | g << 8 | b;
//ビットマップに設定
if (color < 0xffffff) {
_bmpData2.setPixel(x, y, color);
_bmpData1.setPixel(x, y, color);
}
}
}
//ぼかし(エッジのぎざぎざをなくすため)
_bmpData1.applyFilter(_bmpData1, new Rectangle(0, 0, _bmpData1.width, _bmpData1.height), new Point(0,0), _blue);
_bmpData1.unlock();
_bmpData2.unlock();
}
}
}