[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
Planck.jsには物体をマウスでつまむためのMouseJointクラスが秘密裏に用意されており、これを使うと前回行ったのと同じようなことをよりきれいに書けます。ただし、このクラスはテスト用の隠しクラスで、ドキュメントには載っていないようです。
<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);
this._initializeInput();
}
_initializeInput(){
this.mouseBody = this.world.createBody();
canvas.onmousedown = (e) => {
if(!this.boxShape.testPoint(this.box.getTransform(), Vec2(e.offsetX, e.offsetY))){return;}
this.mouseJoint = planck.MouseJoint({maxForce:1000000}, this.mouseBody, this.box, Vec2(e.offsetX, e.offsetY));
this.world.createJoint(this.mouseJoint);
};
canvas.onmousemove = (e) => {
if(this.mouseJoint){
this.mouseJoint.setTarget(Vec2(e.offsetX, e.offsetY));
}
};
canvas.onmouseleave = canvas.onmouseup = (e) => {
if(this.mouseJoint){
this.world.destroyJoint(this.mouseJoint);
this.mouseJoint = null;
}
};
}
_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(boxShape){
var massData = {center:Vec2()};
boxShape.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._drawBox(context);
this._drawMouseJoint(context);
}
_drawMouseJoint(context){
if(!this.mouseJoint){return;}
context.strokeStyle = "orange";
context.beginPath();
var anchorA = this.mouseJoint.getAnchorA();
context.lineTo(anchorA.x, anchorA.y);
var anchorB = this.mouseJoint.getAnchorB();
context.lineTo(anchorB.x, anchorB.y);
context.stroke();
}
_drawBox(context){
for(var fixture = this.box.getFixtureList(); fixture; fixture = fixture.getNext()){
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>
これは前回と同じように、マウスでブロックをつまんで引っ張れるプログラムです。
前回はロジックをすべて自前で書きましたが、同じようなことは既に用意されているMouseJointクラスを使ってもでき、こっちのほうが楽です。
ただし、MouseJoint.jsには不吉なコメントが書かれており、それによるとこのクラスはテスト用に開発されていて、それゆえマニュアルには書かれていないのだそうです。ということは、将来MouseJointの仕様が変更され、MouseJointを使っているプログラムが新しいバージョンのPlanck.jsでは動かなくなる可能性もあるということです。これを使うときには覚悟すべきかもしれません。もっとも、マニュアルに書かれたクラスだって変更される可能性はないわけではないですが。