1
\$\begingroup\$

I am developing a game where a body is moved within the scene using touch. The scene has a boundary wall made up of static rectangular bodies. When I move the object along the boundaries, on collision, it jitters.

This is because the boundary wall pushes the body outwards while the touch pushes it against the wall. I am using linear velocity to move the body using touch. I tried to avoid this by setting the linear velocity of the body to 0 on collision with the boundary wall but it didn't work. I am trying to have a smooth movement along the boundary walls with no jitters. How can I solve this?

Following snippet moves the body on touch. Linear velocity vector has direction towards the touch point. The movement is smooth within the play area but not at the boundaries.

 case TouchEvent.ACTION_MOVE:

                strikerBody.setLinearVelocity((pSceneTouchEvent.getX()-body.getPosition().x * PIXEL_TO_METER_RATIO_DEFAULT),(pSceneTouchEvent.getY()-body.getPosition().y * PIXEL_TO_METER_RATIO_DEFAULT));

These are the bounadry walls:

final Rectangle groundLeft = new Rectangle(camera.getWidth() / 2 - camera.getWidth() / 4, 1, camera.getWidth()/2, 20, this.resourcesManager.vbom);
        final Rectangle groundRight = new Rectangle(camera.getWidth() / 2 + camera.getWidth() / 4, 1, camera.getWidth()/2, 20, this.resourcesManager.vbom);

    final Rectangle roofLeft = new Rectangle(camera.getWidth() / 2 - camera.getWidth() / 4, camera.getHeight() - 1, camera.getWidth()/2, 20, this.resourcesManager.vbom);
    final Rectangle roofRight = new Rectangle(camera.getWidth() / 2 + camera.getWidth() / 4, camera.getHeight() - 1, camera.getWidth()/2, 20, this.resourcesManager.vbom);

    final Rectangle leftTop = new Rectangle(1, camera.getHeight() / 2  + camera.getHeight() / 4 + camera.getHeight() / 12 + camera.getHeight() / 16 , 20, camera.getHeight()/2 - camera.getHeight()/12, this.resourcesManager.vbom);
    final Rectangle leftBottom = new Rectangle(1, camera.getHeight() / 2  - camera.getHeight() / 4 - camera.getHeight() / 12 - camera.getHeight() / 16, 20, camera.getHeight()/2 - camera.getHeight()/12, this.resourcesManager.vbom);

    final Rectangle rightTop = new Rectangle(camera.getWidth() - 1, camera.getHeight() / 2  + camera.getHeight() / 4 + camera.getHeight() / 12 + camera.getHeight() / 16, 20, camera.getHeight()/2 - camera.getHeight()/12, this.resourcesManager.vbom);
    final Rectangle rightBottom = new Rectangle(camera.getWidth() - 1, camera.getHeight() / 2  - camera.getHeight() / 4 - camera.getHeight() / 12 - camera.getHeight() / 16, 20, camera.getHeight()/2 - camera.getHeight()/12, this.resourcesManager.vbom);final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, groundLeft, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, groundRight, BodyType.StaticBody, wallFixtureDef).setUserData("wall");

    PhysicsFactory.createBoxBody(this.mPhysicsWorld, roofLeft, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, roofRight, BodyType.StaticBody, wallFixtureDef).setUserData("wall");

    PhysicsFactory.createBoxBody(this.mPhysicsWorld, leftTop, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, leftBottom, BodyType.StaticBody, wallFixtureDef).setUserData("wall");

    PhysicsFactory.createBoxBody(this.mPhysicsWorld, rightTop, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, rightBottom, BodyType.StaticBody, wallFixtureDef).setUserData("wall");

    this.attachChild(groundLeft);
    this.attachChild(groundRight);
    this.attachChild(roofLeft);
    this.attachChild(roofRight);
    this.attachChild(leftTop);
    this.attachChild(leftBottom);
    this.attachChild(rightTop);
    this.attachChild(rightBottom);
\$\endgroup\$
3
  • \$\begingroup\$ If you posted code I could help more. When you reach a boundary you should have a vector perpendicular to the boundary and add it to the body movement. You can do it so the force slowly increases until you hit the boundary. \$\endgroup\$
    – pangaea
    Jul 23, 2013 at 23:01
  • \$\begingroup\$ I remember reading something (the manual?) that said Box2D is best when simulating objects between .1 meters and 10 meters... I can't tell from your code since I don't know Box2D, but are you simulating objects that Box2D thinks are larger then 10 meters, I remember reading this causes the objects to be jittery... Can anyone back this up? \$\endgroup\$ Jul 24, 2013 at 0:48
  • \$\begingroup\$ The code you are seeing is for the static bodies, they do not move. They are like a boundary wall, on 4 sides of the screen. A small sized dynamic body is moved within these walls using touch. Jitters only happen when the dynamic object is constantly hit against the wall. As described in the question, the static wall body pushes it outward and when Touch pushes it towards the wall jitters happen. \$\endgroup\$
    – Haider
    Jul 24, 2013 at 8:21

3 Answers 3

1
\$\begingroup\$

So were going to get a little tricky here.

Create a second object that is an exact clone of your first one and attach them with a weld joint. These objects should not collide with each other and the one of them should collide with everything but the wall and one should collide with only the wall.

Duplicate your walls too, if its static don’t worry about the weld joint. If you need them to stay in the same location use the weld joint. This should only collide with the new object being touched.

The two new objects should only collide with each other. Next set both their restitution and friction to 0. This should result in no bounce or rotational forces causing the object to simply slide along the wall instead of constantly bouncing off.

\$\endgroup\$
0
0
\$\begingroup\$

Depending of the way you have implemented your physics and graphics, it may be either your dynamic body being too small (or too large) or if your physics and graphics are not synced right. I suspect the former, as many physics libraries (Box2D does it too, if I remember correctly) have a penetration tolerance which allows the bodies to intersect just a little bit. If the penetration tolerance is a notable percent of your body size, it becomes visible as jittery motion when hugging static bodies.

\$\endgroup\$
1
  • \$\begingroup\$ Okay, I'll try to increase/decrease the size of the ball body. Actually, I want an effect similar to Glow Hockey or other such games, where when the paddle is moved along the walls it doesn't shake as much. But in my game it jitters a lot \$\endgroup\$
    – Haider
    Jul 24, 2013 at 8:29
0
\$\begingroup\$

I believe, that setting linear velocity to move body is not great idea. The result of each step calculations is positions and velocities of the bodies. So, when your body collides with a wall, box2d calculates contact impulses, that makes body velocity according to situation. But then, you settting this velocity by hand, and all box2d calculations are breaking down.

I suggest to use impulses or forces to controll a movement. Sure, impulses more preferable, because they allow to achieve better interactivity. To make movement more smooth, you can try linear damping. Also, some manual correction of impulse value can help. For example, make in view current velocity of the body, distance to the touch (farther- stronger), count of touches and etc. Using forces also can make movement more gently. Another good way to move body is use b2MouseJoint or b2MotorJoint.

\$\endgroup\$
2
  • \$\begingroup\$ Actually, I had tried to use linear impulse to move the body on touch. BUT if the touch is quick the impulse pushes the body to one side or the other and the movement is not smooth. Have you tried using impulse to move a body? Any hint, is it the magnitude of impulse causing the trouble for me? \$\endgroup\$
    – Haider
    Jul 25, 2013 at 8:57
  • \$\begingroup\$ @Haider, Im edited the answer. \$\endgroup\$
    – Pavel
    Jul 25, 2013 at 10:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .