Advertisement
MoonlightOwl

Box2DSandbox

Aug 27th, 2015
325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.13 KB | None | 0 0
  1. package totoro.sandbox;
  2.  
  3. import java.util.List;
  4.  
  5. import com.badlogic.gdx.ApplicationListener;
  6. import com.badlogic.gdx.Gdx;
  7. import com.badlogic.gdx.Input;
  8. import com.badlogic.gdx.Input.Keys;
  9. import com.badlogic.gdx.InputAdapter;
  10. import com.badlogic.gdx.graphics.GL20;
  11. import com.badlogic.gdx.graphics.OrthographicCamera;
  12. import com.badlogic.gdx.graphics.g2d.BitmapFont;
  13. import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  14. import com.badlogic.gdx.math.Vector2;
  15. import com.badlogic.gdx.math.Vector3;
  16. import com.badlogic.gdx.physics.box2d.Body;
  17. import com.badlogic.gdx.physics.box2d.BodyDef;
  18. import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
  19. import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
  20. import com.badlogic.gdx.physics.box2d.CircleShape;
  21. import com.badlogic.gdx.physics.box2d.Contact;
  22. import com.badlogic.gdx.physics.box2d.Fixture;
  23. import com.badlogic.gdx.physics.box2d.PolygonShape;
  24. import com.badlogic.gdx.physics.box2d.World;
  25. import com.badlogic.gdx.physics.box2d.WorldManifold;
  26. import com.badlogic.gdx.utils.Array;
  27.  
  28. public class Box2DSand extends InputAdapter implements ApplicationListener {
  29.  
  30.     final static float MAX_VELOCITY = 7f;
  31.     boolean jump = false;
  32.     World world;
  33.     Body player;
  34.     Fixture playerPhysicsFixture;
  35.     Fixture playerSensorFixture;
  36.     OrthographicCamera cam;
  37.     Box2DDebugRenderer renderer;
  38.     Array<MovingPlatform> platforms = new Array<MovingPlatform>();
  39.     MovingPlatform groundedPlatform = null;
  40.     float stillTime = 0;
  41.     long lastGroundTime = 0;
  42.     SpriteBatch batch;
  43.     BitmapFont font;
  44.  
  45.     @Override
  46.     public void create() {
  47.         world = new World(new Vector2(0, -20), true);
  48.         renderer = new Box2DDebugRenderer();
  49.         cam = new OrthographicCamera(28, 20);
  50.         createWorld();
  51.         Gdx.input.setInputProcessor(this);
  52.         batch = new SpriteBatch();
  53.         font = new BitmapFont();
  54.     }
  55.  
  56.     private void createWorld() {
  57.         float y1 = 1; //(float)Math.random() * 0.1f + 1;
  58.         float y2 = y1;
  59.         for(int i = 0; i < 50; i++) {
  60.             Body ground = createEdge(BodyType.StaticBody, -50 + i * 2, y1, -50 + i * 2 + 2, y2, 0);
  61.             y1 = y2;
  62.             y2 = 1; //(float)Math.random() + 1;
  63.         }
  64.  
  65.         Body box = createBox(BodyType.StaticBody, 1, 1, 0);
  66.         box.setTransform(30, 3, 0);
  67.         box = createBox(BodyType.StaticBody, 1.2f, 1.2f, 0);
  68.         box.setTransform(5, 2.4f, 0);
  69.         player = createPlayer();
  70.         player.setTransform(10.0f, 4.0f, 0);
  71.         player.setFixedRotation(true);
  72.  
  73.         for(int i = 0; i < 20; i++) {
  74.             box = createBox(BodyType.DynamicBody, (float)Math.random(), (float)Math.random(), 3);
  75.             box.setTransform((float)Math.random() * 10f - (float)Math.random() * 10f, (float)Math.random() * 10 + 6, (float)(Math.random() * 2 * Math.PI));
  76.         }
  77.  
  78.         for(int i = 0; i < 20; i++) {
  79.             Body circle = createCircle(BodyType.DynamicBody, (float)Math.random() * 0.5f, 3);
  80.             circle.setTransform((float)Math.random() * 10f - (float)Math.random() * 10f, (float)Math.random() * 10 + 6, (float)(Math.random() * 2 * Math.PI));
  81.         }
  82.  
  83.         platforms.add(new MovingPlatform(-2, 3, 2, 0.5f, 2, 0, 4));
  84.         platforms.add(new MovingPlatform(17, 3, 5, 0.5f, 0, 2, 5));
  85.         platforms.add(new MovingPlatform(-7, 5, 2, 0.5f, -2, 2, 8));
  86. //      platforms.add(new MovingPlatform(40, 3, 20, 0.5f, 0, 2, 5));
  87.     }
  88.  
  89.     private Body createBox(BodyType type, float width, float height, float density) {
  90.         BodyDef def = new BodyDef();
  91.         def.type = type;
  92.         Body box = world.createBody(def);
  93.  
  94.         PolygonShape poly = new PolygonShape();
  95.         poly.setAsBox(width, height);
  96.         box.createFixture(poly, density);
  97.         poly.dispose();
  98.  
  99.         return box;
  100.     }
  101.  
  102.     private Body createEdge(BodyType type, float x1, float y1, float x2, float y2, float density) {
  103.         BodyDef def = new BodyDef();
  104.         def.type = type;
  105.         Body box = world.createBody(def);
  106.  
  107.         PolygonShape poly = new PolygonShape();
  108.         poly.setAsBox(x2 - x1, y2 - y1);
  109.         box.createFixture(poly, density);
  110.         box.setTransform(x1, y1, 0);
  111.         poly.dispose();
  112.  
  113.         return box;
  114.     }
  115.  
  116.     private Body createCircle(BodyType type, float radius, float density) {
  117.         BodyDef def = new BodyDef();
  118.         def.type = type;
  119.         Body box = world.createBody(def);
  120.  
  121.         CircleShape poly = new CircleShape();
  122.         poly.setRadius(radius);
  123.         box.createFixture(poly, density);
  124.         poly.dispose();
  125.  
  126.         return box;
  127.     }
  128.  
  129.     private Body createPlayer() {
  130.         BodyDef def = new BodyDef();
  131.         def.type = BodyType.DynamicBody;
  132.         Body box = world.createBody(def);
  133.  
  134.         PolygonShape poly = new PolygonShape();
  135.         poly.setAsBox(0.45f, 1.4f);
  136.         playerPhysicsFixture = box.createFixture(poly, 1);
  137.         poly.dispose();
  138.  
  139.         CircleShape circle = new CircleShape();
  140.         circle.setRadius(0.45f);
  141.         circle.setPosition(new Vector2(0, -1.4f));
  142.         playerSensorFixture = box.createFixture(circle, 0);
  143.         circle.dispose();
  144.  
  145.         box.setBullet(true);
  146.  
  147.         return box;
  148.     }
  149.  
  150.     @Override
  151.     public void resume() {
  152.  
  153.     }
  154.  
  155.     @Override
  156.     public void render() {
  157.         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
  158.         cam.position.set(player.getPosition().x, player.getPosition().y, 0);
  159.         cam.update();
  160.         //cam.apply(Gdx.gl10);
  161.         renderer.render(world, cam.combined);
  162.  
  163.         Vector2 vel = player.getLinearVelocity();
  164.         Vector2 pos = player.getPosition();
  165.         boolean grounded = isPlayerGrounded(Gdx.graphics.getDeltaTime());
  166.         if(grounded) {
  167.             lastGroundTime = System.nanoTime();
  168.         } else {
  169.             if(System.nanoTime() - lastGroundTime < 100000000) {
  170.                 grounded = true;
  171.             }
  172.         }
  173.  
  174.         // cap max velocity on x
  175.         if(Math.abs(vel.x) > MAX_VELOCITY) {
  176.             vel.x = Math.signum(vel.x) * MAX_VELOCITY;
  177.             player.setLinearVelocity(vel.x, vel.y);
  178.         }
  179.  
  180.         // calculate stilltime & damp
  181.         if(!Gdx.input.isKeyPressed(Keys.A) && !Gdx.input.isKeyPressed(Keys.D)) {
  182.             stillTime += Gdx.graphics.getDeltaTime();
  183.             player.setLinearVelocity(vel.x * 0.9f, vel.y);
  184.         }
  185.         else {
  186.             stillTime = 0;
  187.         }
  188.  
  189.         // disable friction while jumping
  190.         if(!grounded) {
  191.             playerPhysicsFixture.setFriction(0f);
  192.             playerSensorFixture.setFriction(0f);
  193.         } else {
  194.             if(!Gdx.input.isKeyPressed(Keys.A) && !Gdx.input.isKeyPressed(Keys.D) && stillTime > 0.2) {
  195.                 playerPhysicsFixture.setFriction(100f);
  196.                 playerSensorFixture.setFriction(100f);
  197.             }
  198.             else {
  199.                 playerPhysicsFixture.setFriction(0.2f);
  200.                 playerSensorFixture.setFriction(0.2f);
  201.             }
  202.  
  203.             if(groundedPlatform != null && groundedPlatform.dist == 0) {
  204.                 player.applyLinearImpulse(0, -24, pos.x, pos.y, true);
  205.             }
  206.         }
  207.  
  208.         // apply left impulse, but only if max velocity is not reached yet
  209.         if(Gdx.input.isKeyPressed(Keys.A) && vel.x > -MAX_VELOCITY) {
  210.             player.applyLinearImpulse(-2f, 0, pos.x, pos.y, true);
  211.         }
  212.  
  213.         // apply right impulse, but only if max velocity is not reached yet
  214.         if(Gdx.input.isKeyPressed(Keys.D) && vel.x < MAX_VELOCITY) {
  215.             player.applyLinearImpulse(2f, 0, pos.x, pos.y, true);
  216.         }
  217.  
  218.         // jump, but only when grounded
  219.         if(jump) {
  220.             jump = false;
  221.             if(grounded) {
  222.                 player.setLinearVelocity(vel.x, 0);
  223.                 System.out.println("jump before: " + player.getLinearVelocity());
  224.                 player.setTransform(pos.x, pos.y + 0.01f, 0);
  225.                 player.applyLinearImpulse(0, 30, pos.x, pos.y, true);
  226.                 System.out.println("jump, " + player.getLinearVelocity());
  227.             }
  228.         }
  229.  
  230.         // update platforms
  231.         for(int i = 0; i < platforms.size; i++) {
  232.             MovingPlatform platform = platforms.get(i);
  233.             platform.update(Math.max(1/30.0f, Gdx.graphics.getDeltaTime()));
  234.         }
  235.  
  236.         // le step...
  237.         world.step(Gdx.graphics.getDeltaTime(), 4, 4);
  238.         player.setAwake(true);
  239.  
  240.         cam.project(point.set(pos.x, pos.y, 0));
  241.         batch.begin();
  242.         font.draw(batch, "friction: " + playerPhysicsFixture.getFriction() + "\ngrounded: " + grounded, point.x+20, point.y);
  243.         batch.end();
  244.     }
  245.  
  246.     private boolean isPlayerGrounded(float deltaTime) {
  247.         groundedPlatform = null;
  248.         Array<Contact> contactList = world.getContactList();
  249.         for(int i = 0; i < contactList.size; i++) {
  250.             Contact contact = contactList.get(i);
  251.             if(contact.isTouching() && (contact.getFixtureA() == playerSensorFixture ||
  252.                     contact.getFixtureB() == playerSensorFixture)) {
  253.  
  254.                 Vector2 pos = player.getPosition();
  255.                 WorldManifold manifold = contact.getWorldManifold();
  256.                 boolean below = true;
  257.                 for(int j = 0; j < manifold.getNumberOfContactPoints(); j++) {
  258.                     below &= (manifold.getPoints()[j].y < pos.y - 1.5f);
  259.                 }
  260.  
  261.                 if(below) {
  262.                     if(contact.getFixtureA().getUserData() != null && contact.getFixtureA().getUserData().equals("p")) {
  263.                         groundedPlatform = (MovingPlatform)contact.getFixtureA().getBody().getUserData();
  264.                     }
  265.  
  266.                     if(contact.getFixtureB().getUserData() != null && contact.getFixtureB().getUserData().equals("p")) {
  267.                         groundedPlatform = (MovingPlatform)contact.getFixtureB().getBody().getUserData();
  268.                     }
  269.                     return true;
  270.                 }
  271.  
  272.                 return false;
  273.             }
  274.         }
  275.         return false;
  276.     }
  277.  
  278.     @Override
  279.     public void resize(int width, int height) {
  280.  
  281.     }
  282.  
  283.     @Override
  284.     public void pause() {
  285.  
  286.     }
  287.  
  288.     @Override
  289.     public void dispose() {
  290.  
  291.     }
  292.  
  293.     @Override
  294.     public boolean keyDown(int keycode) {
  295.         if(keycode == Keys.W) jump = true;
  296.         return false;
  297.     }
  298.  
  299.     @Override
  300.     public boolean keyUp(int keycode) {
  301.         if(keycode == Keys.W) jump = false;
  302.         return false;
  303.     }
  304.  
  305.     Vector2 last = null;
  306.     Vector3 point = new Vector3();
  307.  
  308.     @Override
  309.     public boolean touchDown(int x, int y, int pointerId, int button) {
  310.         cam.unproject(point.set(x, y, 0));
  311.  
  312.         if(button == Input.Buttons.LEFT) {
  313.             if(last == null) {
  314.                 last = new Vector2(point.x, point.y);
  315.             } else {
  316.                 createEdge(BodyType.StaticBody, last.x, last.y, point.x, point.y, 0);
  317.                 last.set(point.x, point.y);
  318.             }
  319.         } else {
  320.             last = null;
  321.         }
  322.  
  323.         return false;
  324.     }
  325.  
  326.     class MovingPlatform {
  327.         Body platform;
  328.         Vector2 pos = new Vector2();
  329.         Vector2 dir = new Vector2();
  330.         float dist = 0;
  331.         float maxDist = 0;
  332.  
  333.         public MovingPlatform(float x, float y, float width, float height, float dx, float dy, float maxDist) {
  334.             platform = createBox(BodyType.KinematicBody, width, height, 1);
  335.             pos.x = x;
  336.             pos.y = y;
  337.             dir.x = dx;
  338.             dir.y = dy;
  339.             this.maxDist = maxDist;
  340.             platform.setTransform(pos, 0);
  341.             platform.getFixtureList().get(0).setUserData("p");
  342.             platform.setUserData(this);
  343.         }
  344.  
  345.         public void update(float deltaTime) {
  346.             dist += dir.len() * deltaTime;
  347.             if(dist > maxDist) {
  348.                 //dir.mul(-1);
  349.                 dist = 0;
  350.             }
  351.  
  352.             platform.setLinearVelocity(dir);
  353.         }
  354.     }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement