0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

plunkerで liquidfun その14

Posted at

概要

plunkerで liquidfunやってみた。
練習問題やってみた。

練習問題

エレベーターをシミュレーションせよ。

写真

image.png

サンプルコード




var world = null;
var FPS = 1000 / 60;
var CIRCLE_VOLUME = 20;
var GRAVITY = 30;
var STAGE_WIDTH = 456;
var STAGE_HEIGHT = 456;
var SCALE = 10;
var ITEM_TYPE_CIRCLE = "item_type_circle";
var ITEM_TYPE_POLYGON = "item_type_polygon";
var physicsEngine = PhysicsEngine();
var viewer = Viewer({
	id: "canvas"
});
function PhysicsEngine() {
	var gravity_ = GRAVITY;
	var items_ = [];
	world = new b2World(new b2Vec2(0, gravity_));
	for (i = 0; i < 7; i++)
	{
		items_.push(createStaticWall_({
			width: 50,
			height: 10,
			x: 380,
			y: 80 + i * 50
		}));
	}
	items_.push(createStaticWall_({
		width: 20,
		height: STAGE_HEIGHT,
		x: STAGE_WIDTH - 20,
		y: 0
	}));
	items_.push(createStaticRect_({
		angle: 20,
		width: 240,
		height: 10,
		x: 150,
		y: 270
	}));
	for (i = 0; i < 7; i++)
	{
		items_.push(createDynamicCircle_({
			radius: 10,
			x: 110 + i * 30,
			y: 0,
		}));
	}
	return {
		update: update,
		getItems: getItems
	};
	function update() {
		world.Step(FPS / 1000, 10, 10);
	}
	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.SetAsBoxXY(width, height);
		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 createStaticRect_(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);
		bodyDef.angle = Math.PI / 180 * params.angle;
		var body = world.CreateBody(bodyDef);
		var shape = new b2PolygonShape;
		//shape.SetAsBoxXY(width, height);
		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 createDynamicCircle_(params) {
		var radius = params.radius / SCALE;
		var x = params.x / SCALE;
		var y = params.y / SCALE;
		var bodyDef = new b2BodyDef();
		bodyDef.type = b2_dynamicBody;
		bodyDef.linearDamping = 0.4;
		bodyDef.linearVelocity = new b2Vec2(15.0, -2.0);
		bodyDef.position.Set(x, y);
		var shape = new b2CircleShape();
		shape.radius = radius;
		var fixDef = new b2FixtureDef;
		fixDef.restitution = 1;
		fixDef.shape = shape;
		fixDef.density = 0.4;
		fixDef.friction = 0.9;
		fixDef.restitution = 0.9;
		var body = world.CreateBody(bodyDef);
		body.CreateFixtureFromDef(fixDef);
		return {
			type: ITEM_TYPE_CIRCLE,
			body: body,
			shape: shape
		};
	}
}
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;
			var angle = null;
			if (item.type === ITEM_TYPE_CIRCLE)
			{
				position = item.body.GetPosition();
				context_.beginPath();
				context_.arc(position.x * SCALE, position.y * SCALE, item.shape.radius * SCALE, 0, Math.PI * 2, true);
				context_.closePath();
				context_.strokeStyle = "rgb(229, 178, 178)";
				context_.lineWidth = 1;
				context_.stroke();
				context_.fillStyle = "rgba(229, 178, 178, 0.5)";
				context_.fill();
			}
			else if (item.type === ITEM_TYPE_POLYGON)
			{
				position = item.body.GetPosition();
				angle = item.body.GetAngle();
				context_.save();
				context_.translate(position.x * SCALE, position.y * SCALE);
				context_.rotate(angle);
				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) , (vector.y * SCALE) );
					} 
					else 
					{
						context_.lineTo((vector.x * SCALE), (vector.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();
				context_.restore();
			}
		}
	}
}
setInterval(function() {
	var items = physicsEngine.getItems();
	for (var i = 0; i < 7; i++)
	{
		var p = items[i].body.GetPosition();
		var a = items[i].body.GetAngle();
		if (p.y < 0.5)
		{
	 		items[i].body.SetTransform(new b2Vec2(p.x, 35.0), a);
		}
		else
		{
 			items[i].body.SetTransform(new b2Vec2(p.x, p.y - 0.1), a);
		}
	}
	physicsEngine.update();
	viewer.update({
		items: physicsEngine.getItems()
	});
}, FPS);




成果物

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?