我正在使用ContactListener
来监听任何接触,如果检测到球和地面之间的碰撞,球应该向上获得脉冲,这在ContactListener
类的void endContact()
函数中提供。但是这种冲动对任何冲动值都没有影响。对于任何脉冲值,球都会从相同的距离反弹。我做错了什么。以下是完整代码:
public class Game implements ApplicationListener {
World world ;
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=8;
static final int BOX_POSITION_ITERATIONS=3;
static final float WORLD_TO_BOX=0.01f;
static final float BOX_WORLD_TO=100f;
Rectangle ball;
Body body;
@Override
public void create() {
world = new World(new Vector2(0, -100), true);
camera = new OrthographicCamera();
camera.viewportHeight = 480;
camera.viewportWidth = 800;
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(0, 10));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
groundBody.createFixture(groundBox, 0.0f);
//Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(camera.viewportWidth / 8, camera.viewportHeight / 2);
body = world.createBody(bodyDef);
// create a Rectangle to logically represent the ball
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(40f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution =1f;
body.createFixture(fixtureDef);
debugRenderer = new Box2DDebugRenderer();
listener listener1=new listener();
world.setContactListener(listener1);
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}
class listener implements ContactListener
{
@Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
}
@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.setLinearVelocity(0,50000000);
System.out.println("Collision detected");
}
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
};
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
}
}
在原始C++版本中,EndContact 是在 Step 函数中调用的,这是一个您无法更改世界上任何东西的时间,因为引擎仍在使用它。我认为Java版本是相同的。您可能需要记下球已经反弹的事实,并在步骤完成后施加脉冲。
脉冲没有影响的原因是您尝试在末端接触方法中应用脉冲。
在 box2d 联系人侦听器方法中,您不能更改 body 的属性或位置。
你可以这样做
boolean b;
@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
//body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.setLinearVelocity(0,50000000);
b = true;
System.out.println("Collision detected");
}
在你更新的方法.....
if(b)
{
body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
}