PhysicsJSはJavaScriptで実装された物理エンジンライブラリです。
公式ページは
http://wellcaffeinated.net/PhysicsJS/
にあります。
GitHubはここ
https://github.com/wellcaffeinated/PhysicsJS
あんまり日本語の情報がないっぽいので、
ちょといじったときのメモをのせておきます。
PhysicsJSを取ってくる
とりあえず
$ bower install PhysicsJS
でとってくる
http://wellcaffeinated.net/PhysicsJS/installation
にはrequireJSうんぬんとかいてあるけど、とりあえずつかわないでやってみる
とりあえず円を書く
Canvasを使うので、
RendererにCanvasを指定してあげて、
幅と高さと追加する要素のスタイルを指定してRendererをつくります。
作ったRendererはworldにaddします。
あとは実際のObjectをくわえてあげればよいので、
今回はcircleを加えて上げます。
これで円が描画できます。
<html>
<body>
<script type="text/javascript" src="./bower_components/PhysicsJS/dist/physicsjs-full-0.6.0.min.js"></script>
<script type="text/javascript">
Physics(function(world) {
var viewWidth = 500;
var viewHeight = 300;
//描画のためのRenderer追加
var renderer = Physics.renderer('canvas', {
width: viewWidth,
height: viewHeight,
styles: {
'circle' : {
srrokeStyle : '#00FF00',
lineWidth: 1,
fillStyle: '#FF0000',
angleIndicator: '#0000FF'
}
}
});
world.add(renderer);
//円を追加してあげる
world.add(
Physics.body('circle', {
x: 50,
y: 50,
radius: 20
})
);
world.render();
});
</script>
</body>
</html>
円を動かす
tickerを動かして円を動かしてみます。
circleには速度vx,vyを指定してあげます。
あとはtickerを動かします。
Physics.util.ticker.on(function(time, dt) {
world.step(time);
});
Physics.util.ticker.start();
でtickerが動くのと時間が進むごとにstepイベントが発生するので、
stepイベント毎にrender()を呼んで描画してあげればよいです。
Physics(function(world) {
var viewWidth = 500;
var viewHeight = 300;
var renderer = Physics.renderer('canvas', {
width: viewWidth,
height: viewHeight,
styles: {
'circle' : {
srrokeStyle : '#00FF00',
lineWidth: 1,
fillStyle: '#FF0000',
angleIndicator: '#0000FF'
}
}
});
world.add(renderer);
world.add(
Physics.body('circle', {
x: 50,
y: 50,
vx: 0.2,
vy: 0.2,
radius: 20
})
);
world.on('step', function() {
world.render();
});
Physics.util.ticker.on(function(time, dt) {
world.step(time);
});
Physics.util.ticker.start();
});
振る舞いを指定する
Physics.behavior()で振る舞いが指定できるので、
指定してあげます。
今回は
等加速度をあたえる constant-acceleration
境界での衝突を検出する edge-collision-detection
衝突したら反発する body-impulse-response
を与えてみます。
Physics(function(world) {
var viewWidth = 500;
var viewHeight = 300;
var renderer = Physics.renderer('canvas', {
width: viewWidth,
height: viewHeight,
styles: {
'circle' : {
srrokeStyle : '#00FF00',
lineWidth: 1,
fillStyle: '#FF0000',
angleIndicator: '#0000FF'
}
}
});
world.add(renderer);
world.add(
Physics.body('circle', {
x: 50,
y: 50,
vx: 0.2,
vy: 0.2,
radius: 20
})
);
//重力加速度を与える
world.add(Physics.behavior('constant-acceleration'));
//境界を加えてそれを検出
var viewportBounds = Physics.aabb(0, 0, viewWidth, viewHeight);
world.add(Physics.behavior('edge-collision-detection', {
aabb: viewportBounds,
restitution: 0.99,
cof: 0.99
}));
//衝突したら反発
world.add(Physics.behavior('body-impulse-response'));
world.on('step', function() {
world.render();
});
Physics.util.ticker.on(function(time, dt) {
world.step(time);
});
Physics.util.ticker.start();
});
実際に動かしてみるとcanvasの境界にぶつかるとバウンドする円が描画されます。
API
APIは
http://wellcaffeinated.net/PhysicsJS/docs/
にあるので、
いろんなbody(rectangleとかconvex-polygonとか)を追加してみたり、
いろんなbehaviorを指定したりして遊んでみたいと思います。