Perpetuum ponsel

Selamat siang, pengguna habr.com sayang! Ini adalah artikel ketiga tentang topik ini. Saya bekerja sepanjang hari, saya tidak bisa melepaskan diri dari perpustakaan Box2D yang menakjubkan.

Jika Anda belum membaca artikel pertama dan kedua , pastikan untuk melihatnya, itu akan menyenangkan! Saya bekerja di Eclipse , saya menulis di Jawa. Mengapa saya menyebut artikel saya demikian? Baca terus - dan segera semuanya akan menjadi jelas! Spoiler: kita akan membuat mesin gerak abadi kita sendiri (termasuk untuk mobil), dan, mungkin, kita akan membuat mesin itu sendiri!

gambar

Gambar 1. Mesin gerak abadi.

Jadi, hari ini kita akan mencoba untuk mendapatkan sesuatu seperti ini:

gambar

Gambar 2. Mesin dengan mesin.

Ya, ini bukan salah ketik! Hari ini kita akan membuat mesin dengan mesin nyata, itu tidak bisa dibedakan dari yang asli! Ini bukan "kereta" untuk Anda dari artikel pertama .

Untuk menghubungkan libGDX, lihat artikel pertama .

Ini adalah gambar yang menunjukkan bagaimana tampilan perangkat saya. Saya menambahkan paket Utils dengan kelas Constants ke folder Core, yang hanya berisi satu konstanta - jumlah piksel per meter. Ini agar dunia tidak raksasa.

gambar

Gambar 3. Bangunan saya.

Berikut adalah kode untuk kelas DesktopLauncher dari com.mygdx.game.desktop:

Tempel kode ini ke dalam kelas dan lupakan.
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); } } 


Kode berikut untuk kelas MyGdxGame adalah dari paket com.mygdx.game. Semuanya ada dalam kode komentar.

Kami menciptakan dunia dan mesin.
 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; } } 



gambar
Gambar 4. Apa yang kita dapatkan saat kompilasi?

Kami membuat mobil kami motor yang memutar rodanya. Tapi itu bekerja selamanya, karena tidak ada energi yang hilang. Jadi kami menciptakan mesin gerak abadi kami!

Dan Anda bertanya-tanya apa yang ada di akhir level? Kirim tangkapan layar dalam komentar saat Anda pergi. Terima kasih telah membaca artikel sampai akhir! Saya harap Anda dapat membuat mobil Anda sendiri di Box2D!

PS Saya menantikan pertanyaan Anda di komentar! Hidupkan fisika game!

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


All Articles