[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
2D物理エンジンPlanck.jsのサンプルコードを書きました。物体をマウスでつまんで動かします。
<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, Transform = planck.Transform; class Demo{ constructor(){ this.world = this._createWorld(); this._initializeGround(this.world); this._initializeBox(this.world); this._initializeInput(); } _initializeInput(){ canvas.onmousemove = (e) => { this.mousePosition = Vec2(e.offsetX, e.offsetY); }; canvas.onmousedown = (e) => { if(!this.isMouseOverBox){ return; } this.localDragPosition = Transform.mul( new Transform(Vec2(), -this.box.getTransform().q.getAngle()), Vec2(e.offsetX, e.offsetY).sub(this.box.getPosition()) ); }; canvas.onmouseup = () => { this.localDragPosition = null; }; } get isMouseOverBox(){ return this.boxShape.testPoint(this.box.getTransform(), this.mousePosition) } get isMouseButtonDown(){ return this.localDragPosition != 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.boxShape = Box(10, 40); this.box.createFixture(this.boxShape); this.box.setMassData(this._getMassData(this.boxShape)); this.box.setAngle(Math.PI / 6); } _getMassData(boxShape){ var massData = {center:Vec2()}; boxShape.computeMass(massData, 1); return massData; } run(){ window.requestAnimationFrame(() => this.run()); this._update(); this._draw(); } _update(){ if(this.isMouseButtonDown){ this.worldDragPosition = Transform.mul(this.box.getTransform(), this.localDragPosition); this.box.applyForce( this.mousePosition.clone().sub(this.worldDragPosition).mul(10000), this.worldDragPosition, true); } this.world.step(1 / 60); } _draw(){ var context = canvas.getContext("2d"); context.clearRect(0, 0, canvas.width, canvas.height); this._drawBox(context); this._drawDragString(context); } _drawDragString(context){ if(this.isMouseButtonDown){ context.strokeStyle = "orange"; context.lineWidth = 3; context.beginPath(); context.moveTo(this.worldDragPosition.x, this.worldDragPosition.y); context.lineTo(this.mousePosition.x, this.mousePosition.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 = Transform.mul(this.box.getTransform(), vertex); context.lineTo(transformedPosition.x, transformedPosition.y); } context.fill(); } } } function main(){ var demo = new Demo(); demo.run(); } main(); </script>
このプログラムは、物体をマウスでつまんで自由に動かすデモです。マウスを黒いブロックの上に持っていって、ドラッグしてみて下さい。オレンジ色の線が描かれます。このオレンジの線はゴム紐のような性質を持っていて、ひっぱるとブロックがそちら側に引っ張られます。伸びれば伸びるほど、引っ張る力は強くなります。