忍者ブログ

Memeplexes

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

Planck.jsサンプルコード 接触の検出

Planck.jsのサンプルコードを書きました。2つの物体が接触しているとき、それを検知するプログラムです。ゲームで自分の発射した弾が敵に当たったかどうかを判定するのに使えそうですね。


サンプルコード

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

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

<script>

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


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

	_createWorld(){
		var world = World();
		world.setGravity(Vec2(0, 100));
		return world;
	}

	_initializeGround(world){
		var ground = world.createBody();
		ground.createFixture(Edge(Vec2(0, canvas.height), Vec2(400, canvas.height)));
	}

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

		this.boxShape = Box(10, 40);
		this.box.createFixture(this.boxShape);
		this.box.setMassData(this._getMassData(this.boxShape));
	}

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

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

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

		this._isFixtureColliding = new Map();

		for(var contact = this.world.getContactList(); contact != null; contact = contact.getNext()){
			this._isFixtureColliding.set(contact.getFixtureA(), true);
			this._isFixtureColliding.set(contact.getFixtureB(), true);
		}
	}

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

	}

	_drawBox(context){
		for(var fixture = this.box.getFixtureList(); fixture; fixture = fixture.getNext()){
			context.fillStyle = this._isFixtureColliding.get(fixture) ? "orange" : "black";
			context.beginPath();

			for(var vertex of fixture.getShape().m_vertices){
				var transformedPosition = planck.Transform.mul(this.box.getTransform(), vertex);
				context.lineTo(transformedPosition.x, transformedPosition.y);
			}

			context.fill();
		}
	}
}


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

main();

</script>

実行結果

解説

このプログラムは、物体同士が接触しているかどうかを検出し、接触していたらオレンジ色に表示します。

最初空中にブロックが出現します。このときは黒です。どこにも接触していませんからね。しかし重力に引かれて床に接すると、オレンジ色に変化します。

接触を検知するのにはWorld.getContactList()メソッドを使います。これには、現在接している物体のペアがリストになっています。空中にブロックが出現したときこのリストは空ですが、床に接した瞬間リストにブロックと床のペアが登録されるのです。プログラマはこのリストを調べて、表示色を変えたり、ゲーム中で弾とキャラクターが接触したかどうかを判定することが出来ます。

拍手[0回]

PR