@Override public boolean touchDown(int x, int y, int pointer, int newParam) { // translate the mouse coordinates to world coordinates testPoint.set(x, y, 0); camera.unproject(testPoint); // ask the world which bodies are within the given // bounding box around the mouse pointer hitBody = null; world.QueryAABB( callback, testPoint.x - 0.1f, testPoint.y - 0.1f, testPoint.x + 0.1f, testPoint.y + 0.1f); // if we hit something we create a new mouse joint // and attach it to the hit body. if (hitBody != null) { MouseJointDef def = new MouseJointDef(); def.bodyA = groundBody; def.bodyB = hitBody; def.collideConnected = true; def.target.set(testPoint.x, testPoint.y); def.maxForce = 1000.0f * hitBody.getMass(); mouseJoint = (MouseJoint) world.createJoint(def); hitBody.setAwake(true); } else { for (Body box : boxes) world.destroyBody(box); boxes.clear(); createBoxes(); } return false; }
@Override public void render() { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); camera.position.set(circleBody.getPosition().x, circleBody.getPosition().y, 0); camera.update(); renderer.render(world, camera.combined); System.out.println( "player.getPosition().x = " + player.getPosition().x + "\nplayer.getPosition().y = " + player.getPosition().y + "\ncamera.position = " + camera.position); Sprite sprite; sprite = (Sprite) circleBody.getUserData(); // set position and width and height and makes sure it is in the center sprite.setBounds( convertToWorld(circleBody.getPosition().x) - sprite.getWidth() / 2, convertToWorld(circleBody.getPosition().y) - sprite.getHeight() / 2, convertToWorld(circleShape.getRadius() * 2), convertToWorld(circleShape.getRadius() * 2)); tiledMapRenderer.setView(camera); tiledMapRenderer.render(); System.out.println( "Bouncing circle: " + circleBody.getMass() + "\n" + "Player: " + player.getMass()); // world.step(1/45f, 6, 2); world.step(Gdx.graphics.getDeltaTime(), 4, 4); player.setAwake(true); // camera.project(point.set(player.getPosition().x, player.getPosition().y, 0)); // logger.log(); batch.begin(); // Circle.draw(batch); sprite.draw(batch); batch.end(); }
public static void moveTo(Entity entity, Vector2 destination) { Physics physicsComponent = EntityUtil.getComponent(entity, Physics.class); Body body = physicsComponent.getBody(); float mass = body.getMass(); Vector2 currentVelocity = body.getLinearVelocity(); Vector2 position = body.getPosition(); Vector2 desiredVelocity = destination.cpy().sub(position).nor().scl(physicsComponent.getMaxSpeed()); Vector2 impulse = desiredVelocity.sub(currentVelocity).scl(mass); PhysicsUtil.applyImpulse(entity, impulse); }
@Override public boolean touchUp(int x, int y, int arg2, int arg3) { Vector3 coordinates = new Vector3(x, y, 0); camera.unproject(coordinates); if (lastTouchPolygon != null) { Vector2 impulse = new Vector2(coordinates.x, coordinates.y) .sub(lastTouchCoordinates) .scl(lastTouchPolygon.getMass()); Log.log( "LiveMode.touchUp", "applying impulse: " + impulse + " on body: " + lastTouchPolygon.getPosition()); lastTouchPolygon.applyLinearImpulse( impulse, lastTouchPolygonLocalCoordinates.add(lastTouchPolygon.getPosition()), true); lastTouchCoordinates = null; lastTouchPolygon = null; lastTouchPolygonLocalCoordinates = null; } return false; }
/** * adjust the density so that the mass has the given value * * @param mass */ public void changeMass(float mass) { fixture.setDensity(mass / body.getMass() * fixture.getDensity()); body.resetMassData(); }
/** * @param f - fixture that is affected * @return true if force was applied, false otherwise. */ private boolean ApplyToFixture(Fixture f) { float shapeDensity = mUseDensity ? f.getDensity() : mFluidDensity; // don't bother with buoyancy on sensors or fixtures with no density if (f.isSensor() || (shapeDensity == 0)) { return false; } Body body = f.getBody(); mAreac.set(Vector2.Zero); mMassc.set(Vector2.Zero); float area = 0; // Get shape for displacement area calculations Shape shape = f.getShape(); mSC.set(Vector2.Zero); float sarea; switch (shape.getType()) { case Circle: sarea = B2ShapeExtensions.ComputeSubmergedArea( (CircleShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Chain: sarea = B2ShapeExtensions.ComputeSubmergedArea( (ChainShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Edge: sarea = B2ShapeExtensions.ComputeSubmergedArea( (EdgeShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Polygon: sarea = B2ShapeExtensions.ComputeSubmergedArea( (PolygonShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; default: sarea = 0; break; } area += sarea; mAreac.x += sarea * mSC.x; mAreac.y += sarea * mSC.y; float mass = sarea * shapeDensity; mMassc.x += sarea * mSC.x * shapeDensity; mMassc.y += sarea * mSC.y * shapeDensity; mAreac.x /= area; mAreac.y /= area; mMassc.x /= mass; mMassc.y /= mass; if (area < Float.MIN_VALUE) { return false; } if (DEBUG_BUOYANCY) { // Run debug w/HCR to see the effects of different fluid densities / linear drag mFluidDensity = 2f; mLinearDrag = 5; mAngularDrag = 2; } // buoyancy force. mTmp.set(mGravity).scl(-mFluidDensity * area); body.applyForce(mTmp, mMassc, true); // multiply by -density to invert gravity // linear drag. mTmp.set( body.getLinearVelocityFromWorldPoint(mAreac).sub(mFluidVelocity).mul(-mLinearDrag * area)); body.applyForce(mTmp, mAreac, true); // angular drag. float bodyMass = body.getMass(); if (bodyMass < 1) // prevent a huge torque from being generated... { bodyMass = 1; } float torque = -body.getInertia() / bodyMass * area * body.getAngularVelocity() * mAngularDrag; body.applyTorque(torque, true); return true; }
// Get the combined mass of all bodies public float getMass() { float mass = 0; for (Body b : scene.getBodies()) mass += b.getMass(); return mass; }