Box2d Body filled with a texture Libgdx - java

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

Related

LibGDX's Box2D having weird rotation behavior when setting angular velocity

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.

Jbox2d Issues with positioning platforms

I am working on developing a platformer, and everything's working fine, except, I seem to be unable to position the bodies for the static platforms.
// creating all the bodies
BodyDef bdef = new BodyDef();
bdef.position.set(x, y);
bdef.type = BodyType.STATIC;
Body body = world.createBody(bdef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(width, height);
FixtureDef fdef = new FixtureDef();
fdef.friction = 0.3f;
fdef.shape = shape;
body.createFixture(fdef);
This is general code that's used to create every body in the map. The bodies work fine, but they don't line up with the width nor the coordinates of the map that I've set. I've noticed that I must specify the bottom left point as starting point for it to make body, but what else I am missing? Why bodies tend to be bigger and go past the starting point of X and Y?
Bodies in box2d are made from their center points. When you define it's position, you are setting it's center and when you define it's width/height, you are actually setting half the width/height (i.e. the size ends up double what you intended).

Box2D. Trying to understand how much force is needed

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).

How to prevent two objects in collisions from crossing both

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

Libgdx Box2D Velocity is just not fast enough

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

Categories