datchの日記

気がついたら社会人。気になる技術的なことについて少しずつ書いていけたらと思っております。

【Wonderfl移植計画】Liquid10000【4作目】

wonderflのFavoriteTop100にランクインしている作品をCreateJSを使って移植しようという計画。

ライセンスはMITなのを確認していますが、
制作者様の方から何かアクションがあった場合は削除させていただきます。

52位 パーティクル祭りの原点「Liquid10000」を初級者が解説してみる。

移植元のFlashソースコード

CreateJSのデモ



既に掲載元でFlashソースコードで解説がされていますね。




今回、このコードを採用したのは理由がありまして、


BitmapDataライブラリが最近ver1.0.0にアップデートしたので、


perlieNoise()関数が実装されたので早速使ってみました!


基本的にはソースコードにはあまり手を加えない方向で進めていたのですが、


コードが少し重複していたので、一部リファクタリングしています。


さすがにパーティクルが10000個もあると重いですね。


なので、次回は並列処理とか使って10000個でもサクッと動くようにソースコードを修正しておきます!

// EaselJS 0.7
// BitmapData 1.0.0
// -- http://kudox.jp/java-script/createjs-easeljs-bitmapdata

window.onload = init;

var VectorDot = (function()
{
	function VectorDot(_av, _vv, _pv)
	{
		this.av = _av;
		this.vv = _vv;
		this.pv = _pv;
	}
	return VectorDot;
}(window));

var W;
var H;
var stage;
var fill;

var NUMS = 10000;
var bmpDat;
var vectorDat;
var randomSeed = Math.floor(Math.random() * 0xFFFF);
var bmp;
var vectorList;
var rect;
var cTra;

function init()
{
	stage = new createjs.Stage("canvas");
	W = stage.canvas.width;
	H = stage.canvas.height;

	fill = new createjs.Shape();
	fill.graphics.beginFill("#000000").drawRect(0, 0, W, H);
	stage.addChild(fill);

	bmpDat = new createjs.BitmapData(null, W, H, 0xFF000000);
	vectorDat = new createjs.BitmapData(null, W, H, 0xFF000000);
	bmp = new createjs.Bitmap(bmpDat.canvas);
	stage.addChild(bmp);

	rect = new createjs.Rectangle(0, 0, W, H);
	cTra = new createjs.ColorTransform(0, .8, .8, .9, 0, 0, 0, -1);

	// 処理の内容が重複していたので削除
	resetFunc();

	createjs.Ticker.addEventListener("tick", loop);
	createjs.Ticker.setFPS(30);
	stage.addEventListener('stagemousedown', resetFunc);
}

function loop()
{
	bmpDat.colorTransform(rect, cTra);

	// 参照なので代入する意味がないような気がします
	var list = vectorList;
	var len = list.length;

	for(var i = 0; i < len; ++i)
	{
		var dots = list[i];

		var col = vectorDat.getPixel(dots.pv.x, dots.pv.y);
		var r = col >> 16 & 0xFF;
		var g = col >> 8 & 0xFF;

		dots.av.x += (r - 128) * .0005;
		dots.av.y += (g - 128) * .0005;
		dots.vv.x += dots.av.x;
		dots.vv.y += dots.av.y;
		dots.pv.x += dots.vv.x;
		dots.pv.y += dots.vv.y;

		var _posX = dots.pv.x;
		var _posY = dots.pv.y;

		dots.av.x *= .96;
		dots.av.y *= .96;
		dots.vv.x *= .92;
		dots.vv.y *= .92;

		(_posX > W) ? dots.pv.x = 0:
			(_posX < 0) ? dots.pv.x = W : 0;
		(_posY > H) ? dots.pv.y = 0:
			(_posY < 0) ? dots.pv.y = H : 0;

		bmpDat.fillRect(new createjs.Rectangle(dots.pv.x, dots.pv.y, 1, 1), 0xFFFFFFFF);
	}
	stage.update();
}

function resetFunc(e)
{
	randomSeed = Math.floor(Math.random() * 0xFFFF);
	vectorDat.perlinNoise(230, 230, 4, randomSeed, false, true, 1|2|0|0);
	vectorList = new Array();

	for(var i = 0; i < NUMS; ++i)
	{
		var px = Math.random() * 465;
		var py = Math.random() * 465;

		var av = new createjs.Point(0, 0);
		var vv = new createjs.Point(0, 0);
		var pv = new createjs.Point(px, py);

		var hoge = new VectorDot(av, vv, pv);

		vectorList.push(hoge);
	}
}