忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

Planck.jsサンプルコード ロープ

Planck.jsで物体にロープをつなげるサンプルコードを書きました。ロープがつながると、物体は動きを制限されます。


サンプルコード

<canvas id="canvas" width="600" height="600" style="border:solid"></canvas>

<script src="planck.js"></script>

<script>

var World = planck.World,
	Vec2 = planck.Vec2,
	Edge = planck.Edge,
	Circle = planck.Circle;

function fillCircle(context, position, radius){
	context.beginPath();
	context.ellipse(position.x, position.y, radius, radius, 0, 0, 2 * Math.PI);
	context.fill();
}

class Demo{
	constructor(){
		this.world = this._createWorld();
		this._initializeGround(this.world);
		this._initializeCircle(this.world);
	}

	_createWorld(){
		return World(Vec2(0, 100));
	}

	_initializeGround(world){
		var bottomGround = world.createBody();
		bottomGround.createFixture(Edge(Vec2(0, canvas.height), Vec2(canvas.width, canvas.height)), {restitution: 1, friction : 0});

		this.topGround = world.createBody();
		this.topGround.createFixture(Edge(Vec2(0, 0), Vec2(canvas.width, 0)), {restitution: 1, friction: 0});

		var leftGround = world.createBody();
		leftGround.createFixture(Edge(Vec2(0, 0), Vec2(0, canvas.height)), {restitution: 1, friction: 0});

		var rightGround = world.createBody();
		rightGround.createFixture(Edge(Vec2(canvas.width, 0), Vec2(canvas.width, canvas.height)), {restitution: 1, friction: 0});
	}

	_initializeCircle(world){
		this.circle = world.createBody().setDynamic();
		this.circle.setPosition(Vec2(200, 100));
		this.circle.setAngle(Math.PI / 6);

		this.circleShape = Circle(40);
		this.circle.createFixture(this.circleShape, {restitution: 1, friction: 0});
		this.circle.setMassData(this._getMassData(this.circleShape));

		this.rope = new planck.RopeJoint({maxLength:200, localAnchorA:Vec2(), localAnchorB:Vec2()}, this.circle, this.topGround);
		this.world.createJoint(this.rope);
	}

	_getMassData(circleShape){
		var massData = {center:Vec2()};
		circleShape.computeMass(massData, 1);
		return massData;
	}

	run(){
		window.requestAnimationFrame(() => this.run());
		this._update();
		this._draw();
	}

	_update(){
		this.world.step(1 / 60);
	}

	_draw(){
		var context = canvas.getContext("2d");
		context.clearRect(0, 0, canvas.width, canvas.height);
		this._drawCircle(context);

		this._drawRope(context);
	}

	_drawRope(context){
		context.beginPath();
		context.lineTo(this.rope.getAnchorA().x, this.rope.getAnchorA().y);
		context.lineTo(this.rope.getAnchorB().x, this.rope.getAnchorB().y);
		context.stroke();
	}

	_drawCircle(context){
		fillCircle(context, this.circle.getPosition(), this.circleShape.getRadius());
	}
}


function main(){
	var demo = new Demo();
	demo.run();
}

main();

</script>

実行結果

解説

このプログラムはRopeJointクラスの使い方のデモです。黒い球はロープで天井と結び付けられており、壁にぶつかって何度も跳ね返ります。

拍手[0回]

PR