Box2D身体与静态物体碰撞时抖动

我正在开发一个使用触摸在场景中移动物体的游戏。 现场有一个由静止的矩形体组成的边界墙。 当我沿边界移动物体时,发生碰撞时,它会抖动。

这是因为边界墙向外推动身体,而触摸推靠在墙上。 我正在使用线速度来移动使用触摸的身体。 我试图通过设置与边界墙碰撞时的身体的线速度为0来避免这种情况,但是它不起作用。 我试图沿着边界墙顺利地移动,没有任何不安。 我该如何解决这个问题?

以下片段移动身体接触。 线性速度vector具有朝向触摸点的方向。 游乐区内的运动平稳,但不在边界。

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

这些是bounadry墙:

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

所以在这里会有点棘手。

创建第二个对象,它是第一个对象的精确克隆,并用焊接接头连接它们。 这些物体不应该相互碰撞,它们中的一个应该与一切物体碰撞,而只有墙壁碰撞,而且只能碰撞墙壁。

重复你的墙壁,如果它的静态不担心焊缝。 如果您需要将它们留在相同的位置,请使用焊接接头。 这只应该与被触摸的新物体发生碰撞。

这两个新的对象应该只相互碰撞。 接下来将其恢复原状和摩擦力设定为0.这将导致没有反弹或旋转力,导致物体沿着壁滑动而不是不断地弹起。

根据你已经实现的物理和graphics的方式,它可能是你的dynamic身体太小(或太大),或者如果你的物理和graphics没有同步正确。 我怀疑前者,就像许多物理图书馆一样(如果我没有记错的话,Box2D也是这样做的)具有穿透力,允许身体相交一点点。 如果穿透力容忍度是你身体尺寸的显着百分比,那么当拥抱静态身体时,它会变成可见的抖动运动。

我相信,设定线速度移动体不是好主意。 每步计算的结果是身体的位置和速度。 所以,当你的身体与墙壁发生碰撞时,box2d会根据情况计算出接触冲动,使得身体的速度。 但是,那么你手动设定这个速度,所有box2d的计算都打破了。

我建议用冲动或力量来控制一个动作。 当然,冲动更好,因为它们可以达到更好的交互性。 为了使运动更平滑,您可以尝试线性阻尼。 此外,一些手动脉冲值的修正可以帮助。 例如,考虑身体的当前速度,触摸的距离(更远 – 更强),触摸次数等。使用力还可以使得运动更加平缓。 移动主体的另一个好方法是使用b2MouseJoint或b2MotorJoint。