Newtons Cottage Cradle

Hallo lieber Leser! Ich habe bereits den ersten Artikel mit den Grundlagen von Box2D in Eclipse in Java geschrieben. Heute werde ich am Beispiel von Newtons Wiege zeigen, wie die Verbindung von Objekten in dieser wunderbaren physischen Bibliothek konfiguriert wird.

Was erwarten wir zu sehen?

Bild

Abbildung 1. Zu gut!

Auf jeden Fall etwas ganz anderes!

Informationen zum Verbinden von libGDX finden Sie im ersten Artikel.

Die Zusammensetzung des Projekts hat sich nicht geändert:

Bild

Abbildung 2. Das Projekt. Ordner und Pakete.

Ich habe das Utils-Paket mit der Constants-Klasse zum Core-Ordner hinzugefügt, der nur eine Konstante enthält - die Anzahl der Pixel pro Meter. Dies ist so, dass die Welt nicht gigantisch ist.

Hier ist der Code für die DesktopLauncher-Klasse von com.mygdx.game.desktop:

Fügen Sie diesen Code in die Klasse ein und vergessen Sie ihn.
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); } } 


In unserem physikalischen Modell wird der Elastizitätskoeffizient von vorrangiger Bedeutung sein. Je höher es ist, desto mehr Schwingungen macht das Pendel. In Box2D kann der Restitutionsparameter von FixtureDef Werte von 0 bis 1,0f annehmen, wobei 0 absolut nicht elastisch und 1,0f absolut elastisch ist. Das beste Modell von Newtons Wiege, das ich mit Restitution bekommen habe = 0.8f:

Bild

Abbildung 3 Elastizitätskoeffizient = 0,8 f, für mehr Klarheit, Zeitlupe.

Implementierungscode:
 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; } } 


Sie können die Koeffizienten selbst ändern und unterschiedliche Ergebnisse erzielen. Darüber hinaus können Texturen auf Grundelemente angewendet werden, um einen größeren Realismus zu erzielen.

Als nächstes werden GIF-Bilder für verschiedene Werte des Elastizitätskoeffizienten präsentiert.

Bild

Abbildung 4. Elastizitätskoeffizient gleich 1f.

Bild

Abbildung 5. Elastizitätskoeffizient gleich 0,5f.

Bild

Abbildung 6. Elastizitätskoeffizient gleich 0,2f.

Bild

Abbildung 7. Elastizitätskoeffizient gleich 0.

Es gibt viele Ideen, ich versuche die Ergebnisse so weit wie möglich zu verbreiten! Vielen Dank für das Lesen bis zum Ende, ich hoffe, der Artikel war nützlich für Sie! Lassen Sie uns dank der Box2D-Bibliothek echtes Chaos in der Spielwelt zusammenbringen!

PS Ich werde alle Fragen in den Kommentaren beantworten.

Source: https://habr.com/ru/post/de450346/


All Articles