Perpetuum mobile

Bonjour, cher utilisateur habr.com! Ceci est le troisième article sur le sujet. Je travaille toute la journée, je ne peux pas m'arracher à l'incroyable bibliothèque Box2D.

Si vous n'avez pas lu les premier et deuxième articles, regardez bien, ce sera amusant! Je travaille dans Eclipse , j'écris en Java. Pourquoi ai-je appelé mon article ainsi? Lisez la suite - et très bientôt tout deviendra clair! Spoiler: nous ferons notre propre machine à mouvement perpétuel (y compris pour les voitures), et, peut-être, nous créerons la machine elle-même!

image

Figure 1. Machine à mouvement perpétuel.

Donc, aujourd'hui, nous allons essayer d'obtenir quelque chose comme ça:

image

Figure 2. Machine avec moteur.

Oui, ce n'est pas une faute de frappe! Aujourd'hui, nous allons fabriquer une machine avec un vrai moteur, elle sera indiscernable du vrai! Ce n'est pas le «panier» pour vous du premier article.

Pour connecter libGDX, consultez le premier article.

Voici une image montrant à quoi ressemble mon assemblage. 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.

image

Figure 3. Ma version.

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); } } 


Le code suivant pour la classe MyGdxGame provient du package com.mygdx.game. Tout est dans les commentaires du code.

Nous créons le monde et la machine.
 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 Box2DDebugRenderer b2dr; //  private Body box; //   private Body backweel; //   private Body frontweel; private Body floor; private Body triangle; //   private float m = -20; 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(); //   floor = createFloor(); //   triangle = createTriangle(20f, 40f, 30f, -2f, -2f, 5f); triangle = createTriangle(50f, 60f, 80f, -2f, 10f, -2f); triangle = createTriangle(100f, 160f, 200f, -2f, 20f, -2f); triangle = createTriangle(280f, 290f, 300f, -2f, 100f, -2f); //   box = createBox(); //   backweel = createWeel(-1f, 2f); frontweel = createWeel(4.5f, 2f); //        connected(); } //      public void connected() { revJoint(box, backweel, -1f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); revJoint(box, frontweel, 4.5f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); } //   !  ! public void revJoint(Body body1, Body body2, float xo, float yo) { //   RevoluteJointDef rjd = new RevoluteJointDef(); //    rjd.enableMotor = true; //  .      ,  ,  //  .    .   -   ! rjd.motorSpeed = m; //   rjd.maxMotorTorque = 30; rjd.collideConnected = false; rjd.bodyA = body1; rjd.bodyB = body2; rjd.localAnchorA.set(xo, yo); 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) { if (Gdx.input.isKeyPressed(Keys.SPACE)) { box.setLinearVelocity(5, 5); } } //     public void cameraUpdate(float delta) { Vector3 position = camera.position; position.x = box.getPosition().x * Constants.PPM; position.y = box.getPosition().y * Constants.PPM; camera.position.set(position); camera.update(); } //     public Body createBox() { Vector2[] verticles = new Vector2[8]; verticles[0] = new Vector2(2f * 10 / utils.Constants.PPM, 2f * 10 / utils.Constants.PPM); verticles[1] = new Vector2(2f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[2] = new Vector2(-2f * 10 / utils.Constants.PPM, 2f * 10 / utils.Constants.PPM); verticles[3] = new Vector2(-2f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[4] = new Vector2(6f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[5] = new Vector2(6f * 10 / utils.Constants.PPM, 0f * 10 / utils.Constants.PPM); verticles[6] = new Vector2(-1f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[7] = new Vector2(4.5f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); PolygonShape shape = new PolygonShape(); Body fBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.DynamicBody; def.position.set(0, 0); def.fixedRotation = false; fBody = world.createBody(def); shape.set(verticles); //    FixtureDef fd = new FixtureDef(); // ,     fd.shape = shape; //   fd.friction = 0.5f; //   fd.density = 3f; //   fd.restitution = 0.5f; fBody.createFixture(fd); fBody.createFixture(fd); shape.dispose(); return fBody; } //   public Body createWeel(float xo, float yo) { CircleShape shape = new CircleShape(); Body fBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.DynamicBody; def.position.set(xo * 10 / utils.Constants.PPM, yo * 10 / utils.Constants.PPM); def.fixedRotation = false; fBody = world.createBody(def); shape.setRadius(2.0f * 10 / utils.Constants.PPM); //    FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.friction = 0.7f; fd.density = 3f; fd.restitution = 0.5f; fBody.createFixture(fd); shape.dispose(); return fBody; } //   public Body createFloor() { Vector2[] verticles = new Vector2[4]; verticles[0] = new Vector2(-100f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[1] = new Vector2(300f * 10 / utils.Constants.PPM, -2f * 10 / utils.Constants.PPM); verticles[2] = new Vector2(300f * 10 / utils.Constants.PPM, -5f * 10 / utils.Constants.PPM); verticles[3] = new Vector2(-100f * 10 / utils.Constants.PPM, -5f * 10 / utils.Constants.PPM); PolygonShape shape = new PolygonShape(); Body fBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.StaticBody; def.position.set(0, 0); def.fixedRotation = true; fBody = world.createBody(def); shape.set(verticles); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.friction = 0.5f; fd.density = 3f; fd.restitution = 0.5f; fBody.createFixture(fd); shape.dispose(); return fBody; } //    ! public Body createTriangle(float xo, float x1, float x2, float yo, float y1, float y2) { Vector2[] verticles = new Vector2[3]; verticles[0] = new Vector2(xo * 10 / utils.Constants.PPM, yo * 10 / utils.Constants.PPM); verticles[1] = new Vector2(x1 * 10 / utils.Constants.PPM, y1 * 10 / utils.Constants.PPM); verticles[2] = new Vector2(x2 * 10 / utils.Constants.PPM, y2 * 10 / utils.Constants.PPM); PolygonShape shape = new PolygonShape(); Body fBody; BodyDef def = new BodyDef(); def.type = BodyDef.BodyType.StaticBody; def.position.set(0, 0); def.fixedRotation = true; fBody = world.createBody(def); shape.set(verticles); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.friction = 0.5f; fd.density = 10f; fd.restitution = 0f; fBody.createFixture(fd); shape.dispose(); return fBody; } } 



image
Figure 4. Qu'obtenons-nous lors de la compilation?

Nous créons notre voiture un moteur qui fait tourner ses roues. Mais cela fonctionne pour toujours, car il n'y a pas de pertes d'énergie. Ainsi, nous créons notre machine à mouvement perpétuel!

Et vous vous demandez ce qu'il y a à la fin du niveau? Envoyez des captures d'écran dans les commentaires au fur et à mesure. Merci d'avoir lu l'article jusqu'au bout! J'espère que vous pourrez créer votre propre voiture dans Box2D!

PS J'attends vos questions avec impatience dans les commentaires! Vive la physique du jeu!

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


All Articles