牛顿的小屋摇篮

亲爱的读者您好! 我已经用Java的Eclipse在Box2D的基础知识上写了第一篇文章。 今天,以牛顿的摇篮为例,我将展示如何在这个出色的物理库中配置对象的连接。

我们期望看到什么?

图片

图1.太好了!

绝对是完全不同的东西!

有关连接libGDX的信息,请参阅第一篇文章。

该项目的组成没有改变:

图片

图2.项目。 文件夹和包。

我将带有Constants类的Utils包添加到Core文件夹,该文件夹仅包含一个常数-每米的像素数。 这样一来,世界就不再庞大。

这是来自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库,让我们在游戏世界中带来真正的混乱!

附言:我将回答评论中的所有问题。

Source: https://habr.com/ru/post/zh-CN450346/


All Articles