ニュートンのコテージクレードル

こんにちは親愛なる読者! JavaのEclipseでのBox2Dの非常に基本的な最初の記事をすでに書いています。 今日は、ニュートンのゆりかごの例を使用して、この素晴らしい物理ライブラリのオブジェクトの接続を構成する方法を示します。



私たちは何を期待していますか?



画像






図1.良すぎる!



まったくそれとはまったく異なる何か!



libGDXの接続については、 最初の記事を参照してください。



プロジェクトの構成は変更されていません。



画像






図2.プロジェクト。 フォルダーとパッケージ。



ConstantsクラスのUtilsパッケージをCoreフォルダーに追加しました。このフォルダーには、1定数のみ(メートルあたりのピクセル数)が含まれています。 これは、世界が巨大ではないようにするためです。



com.mygdx.game.desktopのDesktopLauncherクラスのコードは次のとおりです。



このコードをクラスに貼り付けて、忘れてください。
package com.mygdx.game.desktop; import com.badlogic.gdx.backends.lwjgl.LwjglApplication; import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; import com.mygdx.game.MyGdxGame; public class DesktopLauncher { public static void main(String[] arg) { LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); //   config.width = 720; //   config.height = 480; config.backgroundFPS = 60; config.foregroundFPS = 60; new LwjglApplication(new MyGdxGame(), config); } }
      
      







物理モデルでは、弾性係数が最も重要です。 値が大きいほど、振り子の振動が大きくなります。 Box2Dでは、FixtureDefの復元パラメーターは0から1.0fの値を取ることができます。0は絶対に伸縮性がなく、1.0fは絶対に伸縮性があります。 反発= 0.8fで得たニュートンのゆりかごの最良のモデル:



画像






図3 弾性係数= 0.8f、より明確にするため、時間経過。



実装コード:
 package com.mygdx.game; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.physics.box2d.Body; import com.badlogic.gdx.physics.box2d.BodyDef; import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; import com.badlogic.gdx.physics.box2d.CircleShape; import com.badlogic.gdx.physics.box2d.FixtureDef; import com.badlogic.gdx.physics.box2d.PolygonShape; import com.badlogic.gdx.physics.box2d.World; import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef; import utils.Constants; public class MyGdxGame extends ApplicationAdapter { private OrthographicCamera camera; private boolean DEBUG = false; private World world; private Body plos; private Body plos2; private Body plos3; private Body plos1; private Body plos4; private Box2DDebugRenderer b2dr; private Body ball; private Body ball1; private Body ball2; private Body ball3; private Body ball4; public void create() { float w = Gdx.graphics.getWidth(); float h = Gdx.graphics.getHeight(); camera = new OrthographicCamera(); camera.setToOrtho(false, w / 2, h / 2); world = new World(new Vector2(0, -9.8f), false); b2dr = new Box2DDebugRenderer(); //     plos = createplos(20 / Constants.PPM); plos1 = createplos(0 / Constants.PPM); plos2 = createplos(40 / Constants.PPM); plos3 = createplos(80 / Constants.PPM); plos4 = createplos(60 / Constants.PPM); //   ball = createball(20 / Constants.PPM); ball1 = createball(40 / Constants.PPM); ball2 = createball(60 / Constants.PPM); ball3 = createball(0 / Constants.PPM); ball4 = createball(80 / Constants.PPM); //       rotation(plos, ball); rotation(plos2, ball1); rotation(plos1, ball3); rotation(plos4, ball2); rotation(plos3, ball4); } //       public void rotation(Body body1, Body body2) { RevoluteJointDef rjd = new RevoluteJointDef(); rjd.bodyA = body1; rjd.bodyB = body2; rjd.collideConnected = false; //      rjd.localAnchorB.set((plos.getPosition().x) / Constants.PPM, plos.getPosition().y / Constants.PPM + 2); //      rjd.localAnchorA.set((plos.getPosition().y - 6.8f) / Constants.PPM, plos.getPosition().x / Constants.PPM); world.createJoint(rjd); } public void render() { update(Gdx.graphics.getDeltaTime()); Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); b2dr.render(world, camera.combined.scl(Constants.PPM)); } public void resize(int width, int height) { camera.setToOrtho(false, width / 2, height / 2); } public void dispose() { world.dispose(); b2dr.dispose(); } public void update(float delta) { world.step(1 / 60f, 6, 2); cameraUpdate(delta); inputUpdate(delta); } public void inputUpdate(float delta) { //    ,      -7 /  x, -7 /  y if (Gdx.input.isKeyPressed(Keys.SPACE)) { ball3.setLinearVelocity(-7, -7); } } //      public void cameraUpdate(float delta) { Vector3 position = camera.position; position.x = ball1.getPosition().x * Constants.PPM; position.y = ball1.getPosition().y * Constants.PPM; camera.position.set(position); camera.update(); } //   public Body createplos(float xo) { PolygonShape shape = new PolygonShape(); Body fBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.StaticBody; def.position.set(xo, 200 / Constants.PPM); def.fixedRotation = true; fBody = world.createBody(def); shape.setAsBox(10 / Constants.PPM, 10 / Constants.PPM); fBody.createFixture(shape, 0.001f); shape.dispose(); return fBody; } //   public Body createball(float xo) { Body pBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.DynamicBody; def.position.set(xo, 100 / Constants.PPM); def.fixedRotation = false; pBody = world.createBody(def); CircleShape shape = new CircleShape(); shape.setRadius(10 / Constants.PPM); pBody.createFixture(shape, 0.0001f); def.bullet = true; FixtureDef fd = new FixtureDef(); //   fd.restitution = 0.8f; //  fd.density = 10.0f; //   fd.friction = 0f; fd.shape = shape; pBody.createFixture(fd); shape.dispose(); return pBody; } }
      
      







係数を自分で変更して、異なる結果を得ることができます。 さらに、テクスチャをプリミティブに適用して、よりリアルに仕上げることができます。



次に、弾性係数のさまざまな値のgif画像を示します。



画像






図4. 1fに等しい弾性係数。



画像






図5. 0.5fに等しい弾性係数。



画像






図6. 0.2fに等しい弾性係数。



画像






図7. 0に等しい弾性係数



たくさんのアイデアがあります、私は可能な限り結果を広めようとします! 最後まで読んでいただきありがとうございます。この記事がお役に立てば幸いです。 Box2Dライブラリのおかげで、ゲームの世界に本当のカオスをもたらしましょう!



PSコメントのすべての質問に答えます。



All Articles