0
\$\begingroup\$

Hey guys I've been learning to make games with LibGDX. I did a tiled map in Tiled and the rest of code in java using Android Studio. I could make a ball bounce on the flour using Box2D, but I can't make this same ball hit some circular or elliptcal objects from certain Tiled's layer. I've been searching for days, but I'm very newbee to this and I can't understand the explanations the figure this out.

What happens when I click run:

It's showing the the ball image falling next to a circular shape (I think it's made by debug renderer) and the tiled image is shown, but the ball doesn't collide. The ball passes through and nothing happens. I can't see any circular shapes near the tiled image. Maybe the problem is in my for in the code below.

Here is my code:

public class MyBallGame extends ApplicationAdapter {
    World world;
    Box2DDebugRenderer debugRenderer;
    OrthographicCamera cam;
    SpriteBatch batch;
    Texture ball;
    Texture bg;
    Body body;
    Body circulo;
    Sprite sprite;
    //TILES
    //private TmxMapLoader maploader;
    private TiledMap map;
    private TiledMapRenderer tiledMapRenderer;
    //private OrthogonalTiledMapRenderer renderer;

    @Override
    public void create () {
        //TILES
        cam = new OrthographicCamera();
        cam.setToOrtho(false,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
        cam.update();

        map = new TmxMapLoader().load("tiles.tmx");
        tiledMapRenderer = new OrthogonalTiledMapRenderer(map);
        world = new World(new Vector2(0, -980), true);
        debugRenderer = new Box2DDebugRenderer();
        batch = new SpriteBatch();
        ball = new Texture("circulo.png");
        sprite = new Sprite(ball);
        // Center the sprite in the top/middle of the screen
        sprite.setPosition(100, 400);

        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(sprite.getX(), sprite.getY());
        // Create a body in the world using our definition
        body = world.createBody(bodyDef);
        // Create a circle shape and set its radius to 6
        CircleShape circle = new CircleShape();
        circle.setRadius(6f);
// Create a fixture definition to apply our shape to
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circle;
        fixtureDef.density = 1.5f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f; // Make it bounce a little bit
// Create our fixture and attach it to the body
        Fixture fixture = body.createFixture(fixtureDef);

        circle.dispose();
//Tiled objects:
        BodyDef bdef = new BodyDef();
        //PolygonShape pshape = new PolygonShape();
        FixtureDef fdef = new FixtureDef();

        for(MapObject object : map.getLayers().get(1).getObjects().getByType(CircleMapObject.class)){
            Circle circ = ((CircleMapObject) object).getCircle();

            bdef.type = BodyDef.BodyType.StaticBody;
            bdef.position.set(0, 0);

            circulo = world.createBody(bdef);
            CircleShape cShape = new CircleShape();
            cShape.setRadius(circ.radius);
            //pshape.setRadius(circ.radius);
            //fdef.shape = pshape;
            fixtureDef.shape = cShape;
            fixtureDef.density = 1.5f;

            body.createFixture(fdef);
        }
    }

    @Override
    public void render () {
        // Advance the world, by the amount of time that has elapsed since the
        //last frame
        // Generally in a real game, dont do this in the render loop, as you are
        //tying the physics
        // update rate to the frame rate, and vice versa
        world.step(Gdx.graphics.getDeltaTime(), 6, 2);

        // Now update the spritee position accordingly to it's now updated
        //Physics body
        sprite.setPosition(body.getPosition().x, body.getPosition().y);

        // You know the rest...
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        //TILES
        cam.update();
        tiledMapRenderer.setView(cam);
        tiledMapRenderer.render();
        debugRenderer.render(world, cam.combined);


        batch.begin();
        batch.draw(sprite, sprite.getX(), sprite.getY());
        batch.end();
    }
}
\$\endgroup\$
  • \$\begingroup\$ Can you elaborate on how it's failing. Is the debug rendering showing the bodies in the positions you expect them to be? \$\endgroup\$ – bornander Feb 2 '16 at 8:03
  • 1
    \$\begingroup\$ A couple of screenshots would be helpful. A gif would be ideal. One handy tool for gif creation is Licecap. \$\endgroup\$ – NauticalMile Feb 2 '16 at 17:55
0
\$\begingroup\$

I had the same Problem with my game and i watch a tutorial series on youtube from Brent Aureli. He is explaining this really well i will put a link right here. Maybe it will help you as well .

https://www.youtube.com/watch?v=tcH6Mp03KC0

Edit: Have you set the CategoryBits? like that

public static final short NOTHING_BIT = 0;
public static final short GROUND_BIT = 1;
public static final short LINK_BIT = 2;
public static final short BRICK_BIT = 4;
public static final short STONE_BIT = 8;

and then you need to write these lines of code for each object you create so that the categorybits can collide with each other:

fdef.filter.categoryBits = GetTheTriforce.LINK_BIT;
fdef.filter.maskBits = GetTheTriforce.GROUND_BIT |
            GetTheTriforce.STONE_BIT |
            GetTheTriforce.BRICK_BIT |
            GetTheTriforce.ENEMY_BIT |
            GetTheTriforce.OBJECT_BIT |
            GetTheTriforce.ENEMY_HEAD_BIT |
            GetTheTriforce.ITEM_BIT|
            GetTheTriforce.END_BIT|
            GetTheTriforce.HOLE_BIT;

so that the whole code should something like that:

BodyDef bdef = new BodyDef();
    bdef.position.set(currentPosition.add(0, 10 / GetTheTriforce.PPM));
    bdef.type = BodyDef.BodyType.DynamicBody;
    b2body = world.createBody(bdef);

    FixtureDef fdef = new FixtureDef();
    CircleShape shape = new CircleShape();
    shape.setRadius(6 / GetTheTriforce.PPM);
    fdef.filter.categoryBits = GetTheTriforce.LINK_BIT;
    fdef.filter.maskBits = GetTheTriforce.GROUND_BIT |
            GetTheTriforce.STONE_BIT |
            GetTheTriforce.BRICK_BIT |
            GetTheTriforce.ENEMY_BIT |
            GetTheTriforce.OBJECT_BIT |
            GetTheTriforce.ENEMY_HEAD_BIT |
            GetTheTriforce.ITEM_BIT|
            GetTheTriforce.END_BIT|
            GetTheTriforce.HOLE_BIT;

    fdef.shape = shape;
    b2body.createFixture(fdef).setUserData(this);
    shape.setPosition(new Vector2(0, -14 / GetTheTriforce.PPM));
    b2body.createFixture(fdef).setUserData(this);

thats just some of the code i used in my game

\$\endgroup\$
  • \$\begingroup\$ Bexx, I watched the same tutorial too. I did the for loop like Brent Aureli did, but my objecst are circurcles (or ellipses, i'm not sure), so maybe that's the problem. I think I didn't get the objects. I don't know what classes and methods to use. \$\endgroup\$ – Igor Lacourt Feb 2 '16 at 23:52
  • \$\begingroup\$ just edited my answer maybe it helps. is this the only code you are using or are there more classes? and whats the general idea behind the game \$\endgroup\$ – Bexx Feb 3 '16 at 23:33
  • \$\begingroup\$ Thanks Bexx, I'm using just 1 class. I made some confusion. I thought the link was to another video that Brent made earlier in the same series about Mario Bros. Since my game is even more simple, I think I figured out how to do the collisions just repeating a sprite with for loop, so I dont need the map. Although, your answer well be very good for me to learn to lead with collisions with tiled objects when I need it! \$\endgroup\$ – Igor Lacourt Feb 4 '16 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.