Search code examples
androidcsslibgdxbox2d

Sprite image leaves its dynamic body after collide with static ground body in Libgdx


i have 3 bodies in my game,a ball dynamic body falling from above,a static ground and a dynamic body on the ground, when ball collide directly with ground or kinematic body under gravity its fine,but when ball collide first with dynamic body on ground and then bounce to ground,a strange thing happens sprite leaves body and fly off the screen. I used Box2DDebugRenderer to figure out that. my code for ground is here if (ground != null) world.destroyBody(ground);

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.StaticBody;

    FixtureDef fixtureDef = new FixtureDef();

    PolygonShape shape = new PolygonShape();
    shape.setAsBox(camera.viewportWidth, 5);

    fixtureDef.shape = shape;
    fixtureDef.friction=0.2f;
    fixtureDef.filter.categoryBits = WORLD_ENTITY;
    fixtureDef.filter.maskBits = PHYSICS_ENTITY;

    ground = world.createBody(bodyDef);
    ground.createFixture(fixtureDef);
    ground.setTransform(0, 0, 0);

    shape.dispose();'

my code for falling body

  public Body dropBall() {
        Body body;
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(MathUtils.random(0,50),50);
        body = world.createBody(bodyDef);
        ballBodies.add(body);
        CircleShape circleShape = new CircleShape();
        circleShape.setPosition(new Vector2(0, 0));
        circleShape.setRadius(25*SCALE);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circleShape;
        fixtureDef.density = 0.1f;
        fixtureDef.restitution = 0.7f;
        fixtureDef.filter.categoryBits = PHYSICS_ENTITY;
        fixtureDef.filter.maskBits = WORLD_ENTITY;
        body.createFixture(fixtureDef);
              circleShape.dispose();


        lastDropTime = TimeUtils.millis();
        return body;


    }

my code for body on ground

 private Body createBody(String name, float x, float y, float rotation) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        Body body = playerPhysics.createBody(name, world, bodyDef, SCALE, SCALE);

        body.setTransform(x, y, rotation);
        body.setLinearDamping(50f);
        body.setGravityScale(0);
        body.setFixedRotation(true);


        return body;
    }

my render method

  @Override
    public void render() {
        Gdx.gl.glClearColor(0.57f, 0.77f, 0.85f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stepWorld();
        viewport.apply();
        elapsedTime+=Gdx.graphics.getDeltaTime();


         position =playerBody.getPosition();

         float width =player.getRegionWidth()*SCALE;
         float height=player.getRegionHeight()*SCALE;

        batch.begin();
            if (Gdx.input.isKeyPressed(Input.Keys.SPACE))
                 batch.draw(headerAnimation.getKeyFrame(elapsedTime,true),position.x,position.y,width,height);
              else  drawSprite("2",position.x,position.y);

        for (Body body : ballBodies) {
            body.applyTorque(torque, false);
            ball.setRotation((float) Math.toDegrees(body.getAngle()));
            batch.draw(ball, body.getPosition().x-ball.getWidth()/2,body.getPosition().y-ball.getWidth()/2, ball.getOriginX()
                    , ball.getOriginY(), ball.getWidth(), ball.getHeight(), ball.getScaleX(), ball.
                            getScaleY(), ball.getRotation());
        }

        if (TimeUtils.millis() - lastDropTime > 3000) dropBall();

        Iterator<Body> iterator = ballBodies.iterator();
        while (iterator.hasNext()) {
            Body body = iterator.next();
            if (body.getPosition().y<=7&&body.getLinearVelocity().len()<0.4f&&
                    body.getAngularVelocity()<0.4f) {

                world.destroyBody(body);
                iterator.remove();
            }
        }

         batch.end();

        debugRenderer.render(world, camera.combined);
    }

code to handle contact in create method

public void beginContact(Contact contact) {
                if((contact.getFixtureA().getBody() == ballBody) &&
                        (contact.getFixtureB().getBody()==playerBody)
                        || (contact.getFixtureA().getBody() == playerBody
                        && contact.getFixtureB().getBody()==ballBody)) {
                    ballBody.applyForceToCenter(20f,20f,true);

                }
                if((contact.getFixtureA().getBody() == ballBody) &&
                        (contact.getFixtureB().getBody()==ground)
                        || (contact.getFixtureA().getBody() == ground
                        && contact.getFixtureB().getBody()==ballBody)) {
                    ballBody.applyForceToCenter(0,50f,true);

                }

            }

there is problem with second collision i.e ground. plz tell me to solve this?


Solution

  • bro,just add this line of code to each of your bodies may be helpful

    body.setFixedRotation=true;