plunkerで liquidfun その2

# 概要
plunkerで liquidfunやってみた。
重力を反転してみた。

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4db13e8b-20c2-8fd7-a646-da3d42bb64cd.png)

# サンプルコード

```

var world = null;
var FPS = 1000 / 60;
var GRAVITY = 20;
var STAGE_WIDTH = 450;
var STAGE_HEIGHT = 450;
var SCALE = 10;
var ITEM_TYPE_PARTICLE = "item_type_particle";
var ITEM_TYPE_POLYGON = "item_type_polygon";
var PARTICLE_DENSITY = Number("3") || 3;
var PARTICLE_SIZE = Number("99") || 100;
var PARTICLE_FLAGS = b2_waterParticle;
switch ("powder")
{
case "elastic":
	PARTICLE_FLAGS = b2_elasticParticle;
break;
case "powder":
	PARTICLE_FLAGS = b2_powderParticle;
break;
case "viscous":
	PARTICLE_FLAGS = b2_viscousParticle;
break;
case "tensile":
	PARTICLE_FLAGS = b2_tensileParticle;
break;
case "colorMixing":
	PARTICLE_FLAGS = b2_colorMixingParticle;
break;
}
var physicsEngine = PhysicsEngine();
var viewer = Viewer({
	id: "canvas"
});
setInterval(function() {
	physicsEngine.update();
	viewer.update({
		items: physicsEngine.getItems()
	});
}, FPS);
setInterval(function() {
	physicsEngine.changeGravity();
}, 20000);
function PhysicsEngine() {
	var gravity_ = GRAVITY;
	var items_ = [];
	world = new b2World(new b2Vec2(0, gravity_));
	items_.push(createStaticWall_({
		width: STAGE_WIDTH,
		height: 20,
		x: 0,
		y: 0
	}));
	items_.push(createStaticWall_({
		width: STAGE_WIDTH,
		height: 20,
		x: 0,
		y: STAGE_HEIGHT - 20
	}));
	items_.push(createStaticWall_({
		width: 20,
		height: STAGE_HEIGHT,
		x: 0,
		y: 0
	}));
	items_.push(createStaticWall_({
		width: 20,
		height: STAGE_HEIGHT,
		x: STAGE_WIDTH - 20,
		y: 0
	}));
	items_.push(createParticle_({
		shapeRadius: PARTICLE_SIZE,
		particleRadius: PARTICLE_DENSITY,
		x: STAGE_WIDTH / 2,
		y: STAGE_HEIGHT / 2
	}));
	return {
		update: update,
		changeGravity: changeGravity,
		getItems: getItems
	};
	function update() {
		world.Step(FPS / 1000, 10, 10);
	}
	function changeGravity() {
		gravity_ = -gravity_;
		world.SetGravity(new b2Vec2(0, gravity_));
	}
	function getItems() {
		return items_;
	}
	function createStaticWall_(params) {
		var width = params.width / SCALE;
		var height = params.height / SCALE;
		var x = params.x / SCALE;
		var y = params.y / SCALE;
		var bodyDef = new b2BodyDef();
		bodyDef.type = b2_staticBody;
		bodyDef.position.Set(x, y);
		var body = world.CreateBody(bodyDef);
		var shape = new b2PolygonShape;
		shape.vertices[0] = new b2Vec2(0, 0);
		shape.vertices[1] = new b2Vec2(width, 0);
		shape.vertices[2] = new b2Vec2(width, height);
		shape.vertices[3] = new b2Vec2(0, height);
		body.CreateFixtureFromShape(shape, 0.5);
		return {
			type: ITEM_TYPE_POLYGON,
			body: body,
			shape: shape
		};
	}
	function createParticle_(params) {
		var shapeRadius = params.shapeRadius / SCALE;
		var particleRadius = params.particleRadius / SCALE;
		var x = params.x / SCALE;
		var y = params.y / SCALE;
		particleSystemDef = new b2ParticleSystemDef();
		particleSystemDef.radius = particleRadius;
		particleSystemDef.dampingStrength = 0.1;
		particleSystem = world.CreateParticleSystem(particleSystemDef);
		var shape = new b2CircleShape();
		shape.radius = shapeRadius;
		var particleGroupDef = new b2ParticleGroupDef();
		particleGroupDef.shape = shape;
		particleGroupDef.position.Set(x, y);
		particleGroupDef.flags = PARTICLE_FLAGS;
		particleSystem.CreateParticleGroup(particleGroupDef);
		return {
			type: ITEM_TYPE_PARTICLE,
			particleSystem: particleSystem,
			particleRadius: particleRadius
		}
	}
}
function Viewer(params) {
	var canvas_ = document.getElementById(params.id);
	var context_ = canvas_.getContext("2d");
	return {
		update: update
	};
	function update(params) {
		var items = params.items;
		context_.clearRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
		var i = 0,
			max;
		for (i = 0, max = items.length; i < max; i = i + 1)
		{
			var item = items[i];
			var position = null;
			if (item.type === ITEM_TYPE_PARTICLE)
			{
				var buffer = item.particleSystem.GetPositionBuffer();
				var j = 0,
					max2;
				for (j = 0, max2 = buffer.length; j < max2; j = j + 2)
				{
					context_.beginPath();
					context_.arc(buffer[j] * SCALE, buffer[j + 1] * SCALE, item.particleRadius * SCALE, 0, Math.PI * 2, true);
					context_.closePath();
					context_.fillStyle = "rgba(229, 178, 178, 1)";
					context_.fill();
				}
			}
			else if (item.type === ITEM_TYPE_POLYGON)
			{
				position = item.body.GetPosition();
				context_.beginPath();
				var j = 0,
					max2;
				for (j = 0, max2 = item.shape.vertices.length; j < max2; j = j + 1)
				{
					var vector = item.shape.vertices[j];
					if (j <= 0)
					{
						context_.moveTo((vector.x * SCALE) + (position.x * SCALE), (vector.y * SCALE) + (position.y * SCALE));
					}
					else
					{
						context_.lineTo((vector.x * SCALE) + (position.x * SCALE), (vector.y * SCALE) + (position.y * SCALE));
					}
				}
				context_.closePath();
				context_.strokeStyle = "rgb(127, 229, 127)";
				context_.lineWidth = 1;
				context_.stroke();
				context_.fillStyle = "rgba(127, 229, 127, 0.5)";
				context_.fill();
			}
		}
	}
}




```

# 成果物

https://embed.plnkr.co/plunk/wfiwdFFpZtVSUBat

以上。