I have a rectangle that I would like to move fast but for what ever reason the faster velocity I use still seems slow. What am I doing wrong? I have also dropped a circle from above onto a surface and even tough I play with gravity it comes down like a ballon...
Some declarations
float velocity = 10000000f;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=6;
static final int BOX_POSITION_ITERATIONS=2;
Gravity, tried everything and they all seem to suck
world = new World(new Vector2(0, -50), true);
The ground my object is moving onto
//ground
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(0, camera.viewportHeight * .08f));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((camera.viewportWidth) * 2, camera.viewportHeight * .08f);
groundBody.createFixture(groundBox, 0.0f);
And then here are my objects:
//ball
bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(new Vector2(camera.viewportWidth * .2f, camera.viewportHeight * .75f));
body = world.createBody(bodyDef);
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(camera.viewportWidth * .035f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 0.5f;
fixtureDef.friction = 0.5f;
fixtureDef.restitution = 0.8f;
body.createFixture(fixtureDef);
body.setLinearVelocity(0,-100);
//slime boy
BodyDef bodyBoxDef = new BodyDef();
bodyBoxDef.type = BodyType.DynamicBody;
bodyBoxDef.position.set(new Vector2(camera.viewportWidth * .08f,camera.viewportHeight * .191f));
bodyBox = world.createBody(bodyBoxDef);
PolygonShape slimeBox = new PolygonShape();
slimeBox.setAsBox(camera.viewportWidth * .04f, camera.viewportHeight * .03f);
FixtureDef fixtureSlimeDef = new FixtureDef();
fixtureSlimeDef.shape = slimeBox;
fixtureSlimeDef.density = 1.0f;
fixtureSlimeDef.friction = 0.0f;
fixtureSlimeDef.restitution = 0.0f;
bodyBox.createFixture(fixtureSlimeDef);
debugRenderer = new Box2DDebugRenderer();
body.applyTorque(1000000000);
bodyBox.setFixedRotation(true);
bodyBox.setBullet(true);
Any one have suggestions to speed up all movement in this?
I have been using a screen 1280 by 720 but I saw from other sources smaller is better so I scaled down to 640 by 260 but still not the preformance I want. How small should I really go?
From the Box2d Manual (Section 2.2):
Box2D is tuned for meters, kilograms, and seconds. So you can consider
the extents to be in meters. Box2D generally works best when objects
are the size of typical real world objects. For example, a barrel is
about 1 meter tall. Due to the limitations of floating point
arithmetic, using Box2D to model the movement of glaciers or dust
particles is not a good idea.
See https://stackoverflow.com/a/4556714/960524
Related
I created a simple dynamic body from a PolygonShape and rendering it as a PolygonSprite rendered by a PolygonSpriteBatch. The rendering works fine, but the physics is not. The translation due to velocity works well, but when I set angular velocity or apply torque the body "orbits" around a point while rotating on its origin too. The problem isn't the origin, as while debugging I noticed that the body's position is also changing. The only rotation shouldn't make the body translate, right?
Here's how it rotates. I've only set angular velocity.
The linear velocity is always equal to 0 as I checked during debugging, but the position changes (which doesn't make any sense), so it should not be a rendering problem caused by a wrong rotation origin.
Here's where I create the body with the polygon.
public DrawableBody createFullBody(float[] vertices, Body body, Texture tex, Vector2 coord){
//in our example: vertices = new float[]{0.0f, 0.0f, 0.0f, 1f, 1f, 1f, 1f, 0.0f};
DrawableBody out = new DrawableBody(); //a class that contains Body and PolygonSprite
ShortArray indices = triangulate(vertices); //uses EarClippingTriangulator
PolygonShape shape = new PolygonShape();
shape.set(vertices);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
fixtureDef.restitution = 0.9f;
Fixture fixture = body.createFixture(fixtureDef);
shape.dispose(); //this is useless now, so we can dispose it.
PolygonRegion region = new PolygonRegion(new TextureRegion(tex), vertices, indices.toArray());
PolygonSprite sprite = new PolygonSprite(region);
body.setTransform(coord, 0);
sprite.setPosition(coord.x, coord.y);
out.body = body;
out.poly = sprite;
return out;
}
And that's how I render the square:
public void render(PolygonSpriteBatch batch, float delta){
Vector2 pos = body.getPosition(); //this changes even if velocity is zero?!?
Vector2 size = model.robotSize; //this is Vector2(0.1f, 0.1f)
float angle = body.getAngle();
d_body.poly.setPosition(pos.x - size.x / 2.0f, pos.y - size.y / 2.0f);
d_body.poly.setSize(size.x, size.y);
d_body.poly.setOrigin(size.x / 2.0f, size.y / 2.0f);
d_body.poly.setRotation(angle);
batch.draw(d_body.poly.getRegion(),
d_body.poly.getX(), d_body.poly.getY(),
d_body.poly.getOriginX(), d_body.poly.getOriginY(),
d_body.poly.getWidth(), d_body.poly.getHeight(),
1.0f, 1.0f,
d_body.poly.getRotation());
}
I'm struggling with this issue for two days now, so any help would really be appreciated.
I'm trying to understand the amount of force i need to move my object. This is how my world is setup and the physics step is done
private void setupWorld() {
mWorld = new World(new Vector2(0f, -9.8f), true);
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(x, y);
body = world.createBody(bodyDef);
PolygonShape box=new PolygonShape();
box.setAsBox(1,1);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = box;
fixtureDef.density = 1f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution = 0.0f;
Fixture fixture = body.createFixture(fixtureDef);
box.dispose();
}
private void doPhysicsStep(float deltaTime) {
float frameTime = Math.min(deltaTime, 0.25f);
accumulator += frameTime;
while (accumulator >= TIME_STEP) {
body.applyForceToCenter(new Vector2(0, 10f), true);
world.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
accumulator -= (TIME_STEP);
}
}
So i've got a 1x1 box with a density 1. Gravity is set at -9.8 and i'm expecting that when I apply an amount of force to my box that is greater than the gravity (in this example i've set it to 10) that the box should start moving up.
But the box doesn't move. I have to set the force to about 80 (i.e. body.applyForceToCenter(new Vector2(0, 80f), true);) before it starts to move the box.
I've considered that this is due to my time step (which i've currently set to 1/60f), but if anything taking that into account would reduce the force I'm applying in each step.
Can someone explain what i'm miscalculating here?
Your box has a mass of 4, not 1, because in method setAsBox(float hx, float hy) hx means half of desired width, and hy means half of desired height. So if you want to have a box 1 x 1 you will call setAsBox(0.5F, 0.5F).
But this doesn't explain why you need a force of 80 to move it, because force of 50 should be enough to make a difference.
Fg = m * g = 9.8 * 4 = 39.2
On my test project on object of mass 4 even the force of 40 is noticeable when applied programmatically (the delay of application start and pressing the button is significant so I avoid it).
I have a simple triangular shape (obstacle) in my game and i would like to fill it with a texture repeatedly. I have looked at the other 2 topics but couldn't find a working solution. How can i fill this triangle with a small image (assume that its called "brickTexture.png" repeatedly?
Here is the code for creating the box2dbody of the obstacle in Obstacle.java
BodyDef bdef = new BodyDef();
bdef.position.set(obstaclePosition);
bdef.type = BodyDef.BodyType.StaticBody;
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
PolygonShape triangle = new PolygonShape();
float vertices1[] ={-50 / PPM, 100 / PPM,
50 / PPM, 100 / PPM,
0 / PPM, 0 / PPM};
triangle.set(vertices1);
fdef.shape = triangle;
b2body.createFixture(fdef);
And this is the triangle
This can easily be achieved by using the classes PolygonRegion and PolygonSpriteBatch and will work for any polygonal shape (not just triangles).
Create the polygon region:
// this will calculate the triangles given your vertices
short triangles[] = new EarClippingTriangulator().computeTriangles(vertices1).toArray();
// use your texture region
PolygonRegion polygonRegion = new PolygonRegion(textureRegion, vertices1, triangles);
Then you need to use the PolygonSpriteBatch to render at the desired position (I presume body position):
polygonSpriteBatch.draw(polygonRegion, x, y);
Make sure you load your texture with Repeat wrap so it can tile:
texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
Class docs: PolygonRegion, EarClippingTriangulator, PolygonSpriteBatch
I want to know how to prevent an object in crossing another. I have a ball and a square which I can move whith my mouse. When my ball is on my square I move it (in top for example) if I go very slowly the ball remains on the square if not it crosses it.
if both of your 2 object have a fixture defined they will not be able to crossing one another this is an exmple of how a dynamic object who will be affected by physics in the BOX2D world must be created , and also this object can't tunneling through a sensor :
public Ball (World world){
this.world = world;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DYNAMIC;
bodyDef.position.set(0.0f/RATE, 0.0f/RATE);
Ballbody = world.createBody(bodyDef);
CircleShape circle = new CircleShape();
radius = (int) (Math.random()*30+15); // you can set a non randum raduis
circle.m_radius = radius/RATE;
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.restitution = 0.8f;
fixtureDef.density = 2.0f;
fixtureDef.friction = 0.3f;
fixtureDef.filter.groupIndex = -1;
Ballbody.createFixture(fixtureDef);
Ballbody.getFixtureList().setUserData("Ballounaton"); // optional
Vec2 ballVec = new Vec2((float) (Math.random()*8+2),0.0f);
Ballbody.setLinearVelocity(ballVec);
}
make sure to define a fixture to your box2d dynamic or static object to avoid tunneling through a sensor like in this exmple :
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.restitution = 0.8f;
fixtureDef.density = 2.0f;
fixtureDef.friction = 0.3f;
fixtureDef.filter.groupIndex = -1;
Ballbody.createFixture(fixtureDef);
according to BOX2D official documentation :
Recall that shapes don’t know about bodies and may be used
independently of the physics simulation. Therefore Box2D provides the
b2Fixture class to attach shapes to bodies. Fixtures hold the
following:
a single shape
broad-phase proxies
density, friction, and restitution
collision filtering flags
back pointer to the parent body
user data
sensor flag
I'm using JBox2d to perform collision detection in a game project I'm working on.
I represent obstacles in the world with static bodies. Whenever a dynamic body (i.e. a game character) collides with one of these obstacles, there is a very noticeable drop in performance. Fps will drop from ~120 to ~5. This seems to happen more frequently when the corners of the static body are collided with.
When I set the body type of the world obstacles to be dynamic instead of static, with very high density(to prevent the body from moving when it is collided with), this issue disappears... This solution is not ideal for my situation however......
Any ideas as to what could be causing this huge fps drop?
Here's the code I use to create the static bodies:
BodyDef def = new BodyDef();
def.type = BodyType.STATIC; // If this line is commented and the other
//commented lines are uncommented, the issue goes away.
//def.type = BodyType.DYNAMIC;
def.position.set(worldBounds.getCenterX(), worldBounds.getCenterY());
Body staticBody = b2World.createBody(def);
PolygonShape box = new PolygonShape();
box.setAsBox(worldBounds.getWidth() * 0.5f, worldBounds.getHeight() * 0.5f);
FixtureDef fixture = new FixtureDef();
fixture.shape = box;
fixture.friction = 0.3f;
//fixture.density = 1000000000;
staticBody.createFixture(fixture);
//staticBody.setSleepingAllowed(true);
//staticBody.setFixedRotation(true);
I've tried using a CircleShape instead of a PolygonShape, but that doesn't help anything.
Thank you!
this is the code from the game im working on at the moment which works fine. hopefully if you copy and paste, change a few variable names and stuff it might sort your problem. im new to box2d so cant tell you exactly where the problem lies. hope it helps.
//bodydef
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.StaticBody;
bodyDef.position.set(position);
body = world.createBody(bodyDef);
//shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(dimension.x / 2, dimension.y / 2);
//fixture
FixtureDef fixture = new FixtureDef();
fixture.friction = 0.3f;
fixture.shape = shape;
body.createFixture(fixture);
shape.dispose();