Berceau du cottage de Newton

Bonjour cher lecteur! J'ai déjà écrit le premier article avec les bases de Box2D dans Eclipse en Java. Aujourd'hui, en utilisant l'exemple du berceau de Newton, je vais montrer comment configurer la connexion des objets dans cette merveilleuse bibliothèque physique.

Qu'attendons-nous de voir?

image

Figure 1. Trop bien!

Certainement quelque chose de totalement différent de ça!

Pour connecter libGDX, consultez le premier article.

La composition du projet n'a pas changé:

image

Figure 2. Le projet. Dossiers et packages.

J'ai ajouté le package Utils avec la classe Constants au dossier Core, qui ne contient qu'une seule constante - le nombre de pixels par mètre. C'est ainsi que le monde n'est pas gigantesque.

Voici le code de la classe DesktopLauncher de com.mygdx.game.desktop:

Collez ce code dans la classe et oubliez-le.
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); } } 


Dans notre modèle physique, le coefficient d'élasticité sera de première importance. Plus il est élevé, plus le pendule fera d'oscillations. Dans Box2D, le paramètre de restitution de FixtureDef peut prendre des valeurs de 0 à 1.0f, où 0 n'est absolument pas élastique et 1.0f est absolument élastique. Le meilleur modèle de berceau de Newton que j'ai obtenu avec restitution = 0,8f:

image

Figure 3 Coefficient d'élasticité = 0,8f, pour plus de clarté, ralenti.

Code de mise en œuvre:
 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; } } 


Vous pouvez modifier les coefficients vous-même et obtenir des résultats différents. De plus, des textures peuvent être appliquées aux primitives pour obtenir un plus grand réalisme.

Ensuite seront présentées des images gif pour différentes valeurs du coefficient d'élasticité.

image

Figure 4. Coefficient d'élasticité égal à 1f.

image

Figure 5. Coefficient d'élasticité égal à 0,5f.

image

Figure 6. Coefficient d'élasticité égal à 0,2f.

image

Figure 7. Coefficient d'élasticité égal à 0.

Il y a beaucoup d'idées, j'essaie de diffuser le plus possible les résultats! Merci d'avoir lu jusqu'au bout, j'espère que l'article vous a été utile! Rassemblons le vrai chaos dans le monde du jeu grâce à la bibliothèque Box2D!

PS Je répondrai à toutes les questions dans les commentaires.

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


All Articles