Search in sources :

Example 1 with Contact

use of com.badlogic.gdx.physics.box2d.Contact in project libgdx by libgdx.

the class Box2DCharacterControllerTest method isPlayerGrounded.

private boolean isPlayerGrounded(float deltaTime) {
    groundedPlatform = null;
    Array<Contact> contactList = world.getContactList();
    for (int i = 0; i < contactList.size; i++) {
        Contact contact = contactList.get(i);
        if (contact.isTouching() && (contact.getFixtureA() == playerSensorFixture || contact.getFixtureB() == playerSensorFixture)) {
            Vector2 pos = player.getPosition();
            WorldManifold manifold = contact.getWorldManifold();
            boolean below = true;
            for (int j = 0; j < manifold.getNumberOfContactPoints(); j++) {
                below &= (manifold.getPoints()[j].y < pos.y - 1.5f);
            }
            if (below) {
                if (contact.getFixtureA().getUserData() != null && contact.getFixtureA().getUserData().equals("p")) {
                    groundedPlatform = (Platform) contact.getFixtureA().getBody().getUserData();
                }
                if (contact.getFixtureB().getUserData() != null && contact.getFixtureB().getUserData().equals("p")) {
                    groundedPlatform = (Platform) contact.getFixtureB().getBody().getUserData();
                }
                return true;
            }
            return false;
        }
    }
    return false;
}
Also used : WorldManifold(com.badlogic.gdx.physics.box2d.WorldManifold) Vector2(com.badlogic.gdx.math.Vector2) Contact(com.badlogic.gdx.physics.box2d.Contact)

Example 2 with Contact

use of com.badlogic.gdx.physics.box2d.Contact in project libgdx by libgdx.

the class Box2DCharacterControllerTest method render.

@Override
public void render() {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    cam.position.set(player.getPosition().x, player.getPosition().y, 0);
    cam.update();
    renderer.render(world, cam.combined);
    Vector2 vel = player.getLinearVelocity();
    Vector2 pos = player.getPosition();
    boolean grounded = isPlayerGrounded(Gdx.graphics.getDeltaTime());
    if (grounded) {
        lastGroundTime = TimeUtils.nanoTime();
    } else {
        if (TimeUtils.nanoTime() - lastGroundTime < 100000000) {
            grounded = true;
        }
    }
    // cap max velocity on x
    if (Math.abs(vel.x) > MAX_VELOCITY) {
        vel.x = Math.signum(vel.x) * MAX_VELOCITY;
        player.setLinearVelocity(vel.x, vel.y);
    }
    // calculate stilltime & damp
    if (!Gdx.input.isKeyPressed(Keys.A) && !Gdx.input.isKeyPressed(Keys.D)) {
        stillTime += Gdx.graphics.getDeltaTime();
        player.setLinearVelocity(vel.x * 0.9f, vel.y);
    } else {
        stillTime = 0;
    }
    // disable friction while jumping
    if (!grounded) {
        playerPhysicsFixture.setFriction(0f);
        playerSensorFixture.setFriction(0f);
    } else {
        if (!Gdx.input.isKeyPressed(Keys.A) && !Gdx.input.isKeyPressed(Keys.D) && stillTime > 0.2) {
            playerPhysicsFixture.setFriction(1000f);
            playerSensorFixture.setFriction(1000f);
        } else {
            playerPhysicsFixture.setFriction(0.2f);
            playerSensorFixture.setFriction(0.2f);
        }
        // character hops :)
        if (groundedPlatform != null && groundedPlatform instanceof MovingPlatform && ((MovingPlatform) groundedPlatform).dist == 0) {
            player.applyLinearImpulse(0, -24, pos.x, pos.y, true);
        }
    }
    // since Box2D 2.2 we need to reset the friction of any existing contacts
    Array<Contact> contacts = world.getContactList();
    for (int i = 0; i < world.getContactCount(); i++) {
        Contact contact = contacts.get(i);
        contact.resetFriction();
    }
    // apply left impulse, but only if max velocity is not reached yet
    if (Gdx.input.isKeyPressed(Keys.A) && vel.x > -MAX_VELOCITY) {
        player.applyLinearImpulse(-2f, 0, pos.x, pos.y, true);
    }
    // apply right impulse, but only if max velocity is not reached yet
    if (Gdx.input.isKeyPressed(Keys.D) && vel.x < MAX_VELOCITY) {
        player.applyLinearImpulse(2f, 0, pos.x, pos.y, true);
    }
    // jump, but only when grounded
    if (jump) {
        jump = false;
        if (grounded) {
            player.setLinearVelocity(vel.x, 0);
            System.out.println("jump before: " + player.getLinearVelocity());
            player.setTransform(pos.x, pos.y + 0.01f, 0);
            player.applyLinearImpulse(0, 40, pos.x, pos.y, true);
            System.out.println("jump, " + player.getLinearVelocity());
        }
    }
    // update platforms
    for (int i = 0; i < platforms.size; i++) {
        Platform platform = platforms.get(i);
        platform.update(Math.max(1 / 30.0f, Gdx.graphics.getDeltaTime()));
    }
    // le step...
    world.step(Gdx.graphics.getDeltaTime(), 4, 4);
    // accum += Gdx.graphics.getDeltaTime();
    // while(accum > TICK) {
    // accum -= TICK;
    // world.step(TICK, 4, 4);
    // }
    player.setAwake(true);
    cam.project(point.set(pos.x, pos.y, 0));
    batch.begin();
    font.draw(batch, "friction: " + playerPhysicsFixture.getFriction() + "\ngrounded: " + grounded, point.x + 20, point.y);
    batch.end();
}
Also used : Vector2(com.badlogic.gdx.math.Vector2) Contact(com.badlogic.gdx.physics.box2d.Contact)

Example 3 with Contact

use of com.badlogic.gdx.physics.box2d.Contact in project libgdx by libgdx.

the class Box2DTest method render.

@Override
public void render() {
    // first we update the world. For simplicity
    // we use the delta time provided by the Graphics
    // instance. Normally you'll want to fix the time
    // step.
    long start = TimeUtils.nanoTime();
    world.step(Gdx.graphics.getDeltaTime(), 8, 3);
    float updateTime = (TimeUtils.nanoTime() - start) / 1000000000.0f;
    // next we clear the color buffer and set the camera
    // matrices
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    camera.update();
    // next we render the ground body
    renderBox(groundBody, 50, 1);
    // next we render each box via the SpriteBatch.
    // for this we have to set the projection matrix of the
    // spritebatch to the camera's combined matrix. This will
    // make the spritebatch work in world coordinates
    batch.getProjectionMatrix().set(camera.combined);
    batch.begin();
    for (int i = 0; i < boxes.size(); i++) {
        Body box = boxes.get(i);
        // that's the box's center position
        Vector2 position = box.getPosition();
        // the rotation angle around the center
        float angle = MathUtils.radiansToDegrees * box.getAngle();
        // the bottom left corner of the box, unrotated
        batch.draw(// the bottom left corner of the box, unrotated
        textureRegion, // the bottom left corner of the box, unrotated
        position.x - 1, // the bottom left corner of the box, unrotated
        position.y - 1, // the rotation center relative to the bottom left corner of the box
        1f, // the rotation center relative to the bottom left corner of the box
        1f, // the width and height of the box
        2, // the width and height of the box
        2, // the scale on the x- and y-axis
        1, // the scale on the x- and y-axis
        1, // the rotation angle
        angle);
    }
    batch.end();
    // next we use the debug renderer. Note that we
    // simply apply the camera again and then call
    // the renderer. the camera.apply() call is actually
    // not needed as the opengl matrices are already set
    // by the spritebatch which in turn uses the camera matrices :)
    debugRenderer.render(world, camera.combined);
    // finally we render all contact points
    renderer.setProjectionMatrix(camera.combined);
    renderer.begin(ShapeType.Point);
    renderer.setColor(0, 1, 0, 1);
    for (int i = 0; i < world.getContactCount(); i++) {
        Contact contact = world.getContactList().get(i);
        // we only render the contact if it actually touches
        if (contact.isTouching()) {
            // get the world manifold from which we get the
            // contact points. A manifold can have 0, 1 or 2
            // contact points.
            WorldManifold manifold = contact.getWorldManifold();
            int numContactPoints = manifold.getNumberOfContactPoints();
            for (int j = 0; j < numContactPoints; j++) {
                Vector2 point = manifold.getPoints()[j];
                renderer.point(point.x, point.y, 0);
            }
        }
    }
    renderer.end();
    // finally we render the time it took to update the world
    // for this we have to set the projection matrix again, so
    // we work in pixel coordinates
    batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    batch.begin();
    font.draw(batch, "fps: " + Gdx.graphics.getFramesPerSecond() + " update time: " + updateTime, 0, 20);
    batch.end();
}
Also used : WorldManifold(com.badlogic.gdx.physics.box2d.WorldManifold) Vector2(com.badlogic.gdx.math.Vector2) Body(com.badlogic.gdx.physics.box2d.Body) MouseJoint(com.badlogic.gdx.physics.box2d.joints.MouseJoint) Contact(com.badlogic.gdx.physics.box2d.Contact)

Example 4 with Contact

use of com.badlogic.gdx.physics.box2d.Contact in project libgdx by libgdx.

the class Box2DTest method createPhysicsWorld.

private void createPhysicsWorld() {
    // we instantiate a new World with a proper gravity vector
    // and tell it to sleep when possible.
    world = new World(new Vector2(0, -10), true);
    float[] vertices = { -0.07421887f, -0.16276085f, -0.12109375f, -0.22786504f, -0.157552f, -0.7122401f, 0.04296875f, -0.7122401f, 0.110677004f, -0.6419276f, 0.13151026f, -0.49869835f, 0.08984375f, -0.3190109f };
    PolygonShape shape = new PolygonShape();
    shape.set(vertices);
    // next we create a static ground platform. This platform
    // is not moveable and will not react to any influences from
    // outside. It will however influence other bodies. First we
    // create a PolygonShape that holds the form of the platform.
    // it will be 100 meters wide and 2 meters high, centered
    // around the origin
    PolygonShape groundPoly = new PolygonShape();
    groundPoly.setAsBox(50, 1);
    // next we create the body for the ground platform. It's
    // simply a static body.
    BodyDef groundBodyDef = new BodyDef();
    groundBodyDef.type = BodyType.StaticBody;
    groundBody = world.createBody(groundBodyDef);
    // finally we add a fixture to the body using the polygon
    // defined above. Note that we have to dispose PolygonShapes
    // and CircleShapes once they are no longer used. This is the
    // only time you have to care explicitly for memory management.
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = groundPoly;
    fixtureDef.filter.groupIndex = 0;
    groundBody.createFixture(fixtureDef);
    groundPoly.dispose();
    // We also create a simple ChainShape we put above our
    // ground polygon for extra funkyness.
    ChainShape chainShape = new ChainShape();
    chainShape.createLoop(new Vector2[] { new Vector2(-10, 10), new Vector2(-10, 5), new Vector2(10, 5), new Vector2(10, 11) });
    BodyDef chainBodyDef = new BodyDef();
    chainBodyDef.type = BodyType.StaticBody;
    Body chainBody = world.createBody(chainBodyDef);
    chainBody.createFixture(chainShape, 0);
    chainShape.dispose();
    createBoxes();
    // You can savely ignore the rest of this method :)
    world.setContactListener(new ContactListener() {

        @Override
        public void beginContact(Contact contact) {
        // System.out.println("begin contact");
        }

        @Override
        public void endContact(Contact contact) {
        // System.out.println("end contact");
        }

        @Override
        public void preSolve(Contact contact, Manifold oldManifold) {
        // Manifold.ManifoldType type = oldManifold.getType();
        // Vector2 localPoint = oldManifold.getLocalPoint();
        // Vector2 localNormal = oldManifold.getLocalNormal();
        // int pointCount = oldManifold.getPointCount();
        // ManifoldPoint[] points = oldManifold.getPoints();
        // System.out.println("pre solve, " + type +
        // ", point: " + localPoint +
        // ", local normal: " + localNormal +
        // ", #points: " + pointCount +
        // ", [" + points[0] + ", " + points[1] + "]");
        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse) {
        // float[] ni = impulse.getNormalImpulses();
        // float[] ti = impulse.getTangentImpulses();
        // System.out.println("post solve, normal impulses: " + ni[0] + ", " + ni[1] + ", tangent impulses: " + ti[0] + ", " + ti[1]);
        }
    });
}
Also used : PolygonShape(com.badlogic.gdx.physics.box2d.PolygonShape) World(com.badlogic.gdx.physics.box2d.World) Contact(com.badlogic.gdx.physics.box2d.Contact) WorldManifold(com.badlogic.gdx.physics.box2d.WorldManifold) Manifold(com.badlogic.gdx.physics.box2d.Manifold) Vector2(com.badlogic.gdx.math.Vector2) ContactImpulse(com.badlogic.gdx.physics.box2d.ContactImpulse) BodyDef(com.badlogic.gdx.physics.box2d.BodyDef) ChainShape(com.badlogic.gdx.physics.box2d.ChainShape) Body(com.badlogic.gdx.physics.box2d.Body) FixtureDef(com.badlogic.gdx.physics.box2d.FixtureDef) ContactListener(com.badlogic.gdx.physics.box2d.ContactListener)

Aggregations

Vector2 (com.badlogic.gdx.math.Vector2)4 Contact (com.badlogic.gdx.physics.box2d.Contact)4 WorldManifold (com.badlogic.gdx.physics.box2d.WorldManifold)3 Body (com.badlogic.gdx.physics.box2d.Body)2 BodyDef (com.badlogic.gdx.physics.box2d.BodyDef)1 ChainShape (com.badlogic.gdx.physics.box2d.ChainShape)1 ContactImpulse (com.badlogic.gdx.physics.box2d.ContactImpulse)1 ContactListener (com.badlogic.gdx.physics.box2d.ContactListener)1 FixtureDef (com.badlogic.gdx.physics.box2d.FixtureDef)1 Manifold (com.badlogic.gdx.physics.box2d.Manifold)1 PolygonShape (com.badlogic.gdx.physics.box2d.PolygonShape)1 World (com.badlogic.gdx.physics.box2d.World)1 MouseJoint (com.badlogic.gdx.physics.box2d.joints.MouseJoint)1