box2djsの作法 その7

# 概要

box2djsの作法、調べてみた。
描いた剛体が落っこちてくるやつやってみた。

# 写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0974817f-6d3e-c8b7-f9c0-cbf4d9a6e396.png)


# サンプルコード

```

var b2Vec2 = Box2D.Common.Math.b2Vec2,
	b2AABB = Box2D.Collision.b2AABB,
	b2BodyDef = Box2D.Dynamics.b2BodyDef,
	b2Body = Box2D.Dynamics.b2Body,
	b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
	b2Fixture = Box2D.Dynamics.b2Fixture,
	b2World = Box2D.Dynamics.b2World,
	b2MassData = Box2D.Collision.Shapes.b2MassData,
	b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
	b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
	b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
	b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
	b2Shape = Box2D.Collision.Shapes.b2Shape,
	b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef,
	b2Joint = Box2D.Dynamics.Joints.b2Joint,
	b2Settings = Box2D.Common.b2Settings;
var world;
var ctx;
var scale = 100;
var PTM = 100;
var shape;
var drawing = false;
var previousMouseX = 0;
var previousMouseY = 0;
var u = new b2Vec2(0, 0);
var anchor = [];
var bodies = [];
var d = 1.0;
mouseX = 0;
mouseY = 0;
var  points = [];
var canvas = document.getElementById("c");
ctx = canvas.getContext('2d');
canvas.width = 460;
canvas.height = 460;
world = new b2World(new b2Vec2(0, 9.5), true);
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("c").getContext("2d"));
debugDraw.SetDrawScale(100.0);
debugDraw.SetFillAlpha(0.5);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);

var groundFixDef = new b2FixtureDef();
groundFixDef.density = 2;
groundFixDef.friction = 0.5;
groundFixDef.restitution = 0.2;
groundFixDef.shape = new b2PolygonShape();
groundFixDef.shape.SetAsBox(2.325, 0.3);
var groundDef = new b2BodyDef();
groundDef.type = b2Body.b2_staticBody;
groundDef.position.Set(2.25, 4.6);
var body =  world.CreateBody(groundDef);
body.CreateFixture(groundFixDef);
groundDef.position.Set(2.25, -0.1);
var body =  world.CreateBody(groundDef);
body.CreateFixture(groundFixDef);
groundFixDef.shape.SetAsBox(0.3, 2.25);
groundDef.position.Set(-0.1, 2.25);
var body =  world.CreateBody(groundDef);
body.CreateFixture(groundFixDef);
groundDef.position.Set(4.6, 2.25);
var body = world.CreateBody(groundDef);
body.CreateFixture(groundFixDef);

canvas.addEventListener('mousemove', function(e) {
	mouseX = e.pageX - this.offsetLeft;
	mouseY = e.pageY - this.offsetTop;
	if (drawing)
	{
		points.push({
			x: mouseX,
			y: mouseY
		});
		ctx.beginPath();
		ctx.lineWidth = 5;
		ctx.strokeStyle = "green";
		ctx.moveTo(points[0].x, points[0].y);
		for (var i = 1; i < points.length; i++)
		{
			ctx.lineTo(points[i].x, points[i].y);
		}
		ctx.stroke();
	}
}, false);
canvas.addEventListener('mousedown', function(e) {
	points.push({
		x: mouseX,
		y: mouseY
	});
	if (!drawing)
	{
		previousMouseX = mouseX;
		previousMouseY = mouseY;
		anchor = [];
		setAnchor(mouseX, mouseY);
		drawing = true;
	}
}, false);
canvas.addEventListener('mouseup', function() {
	points.length = 0;
	drawing = false;
	setAnchor(mouseX, mouseY);
	createBody();
}, false);
function dog_eraseline() {
	for (body = world.GetBodyList(); body; body = body.GetNext())
	{
		if (body.GetUserData() == "line")
		{
			world.DestroyBody(body);
		}
	}
}
function vecMagnitude(v) {
	return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
}
function vecAngle(v1, v2) {
	return (v1.x * v2.x + v1.y * v2.y) / (vecMagnitude(v1) * vecMagnitude(v2));
}
function setAnchor(x, y) {
	anchor.push(new b2Vec2(x, y));
}
function createBody() {
	var boxDef = new b2BodyDef();
	boxDef.type = b2Body.b2_dynamicBody;
	boxDef.position.Set(0, 0);
	var body = world.CreateBody(boxDef);
	for (var i = 0; i < anchor.length - 1; i++)
	{
		var position = new b2Vec2((anchor[i].x + anchor[i + 1].x) / 200, (anchor[i].y + anchor[i + 1].y) / 200);
		var angle = Math.atan2(anchor[i].y - anchor[i + 1].y, anchor[i].x - anchor[i + 1].x);
		var l = vecMagnitude(new b2Vec2(anchor[i].x - anchor[i + 1].x, anchor[i].y - anchor[i + 1].y)) / 100;
		if (anchor.length == 2 && l < 0.05)
		{
			l = 0.05;
		}
		var boxFixDef = new b2FixtureDef();
		boxFixDef.density = d * l * 0.05;
		boxFixDef.friction = 0.5;
		boxFixDef.restitution = 0.1;
		boxFixDef.shape = new b2PolygonShape();
		boxFixDef.shape.SetAsOrientedBox(l / 2, 0.025, position, angle);
		body.CreateFixture(boxFixDef);
	}
	body.SetUserData("line");
	bodies.push(body);
}
document.addEventListener("keydown", function(e) {
	tilt = 0;
	switch (event.keyCode)
	{
	case 32: 
	break;
	case 69:
		dog_eraseline();
	break;
	}
}, false);
function tick() {
	world.Step(1 / 30, 8, 2);
	canvas.width = canvas.width;
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	if (drawing)
	{
		var p = new b2Vec2(0, 0);
		p.x = mouseX - previousMouseX;
		p.y = mouseY - previousMouseY;
		if (vecMagnitude(p) !== 0)
		{
			if (Math.cos(10 / 180 * Math.PI) > vecAngle(p, u))
			{
				setAnchor(previousMouseX, previousMouseY);
			}
			u.x = p.x;
			u.y = p.y;
		}
		previousMouseX = mouseX;
		previousMouseY = mouseY;
	}
	world.DrawDebugData();
	for (body = world.GetBodyList(); body; body = body.GetNext())
	{
		var x = body.GetPosition().x;
		var y = body.GetPosition().y;
		var angle = body.GetAngle();
		switch (body.GetUserData())
		{
		case "circle2":
			var radius = body.GetFixtureList().GetShape().GetRadius();
			ctx.save();
			ctx.translate(x * PTM, y * PTM);
			ctx.rotate(angle * (Math.PI / 180));
			ctx.translate(-x * PTM, -y * PTM);
			ctx.beginPath();
			ctx.arc(x * PTM , y * PTM, radius * PTM, 0, 2 * Math.PI, false);
			ctx.closePath();
			ctx.lineWidth = 5;
			ctx.strokeStyle = "green";
			ctx.fillStyle = "red";
			ctx.stroke();
			ctx.fill();
			ctx.restore();
		break;
		}
	}
	world.ClearForces();
}
window.setInterval(tick, 1000 / 30);




```

# 成果物

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

以上。