这是我的代码:
public class Physics3 extends ApplicationAdapter {
SpriteBatch batch;
Sprite sprite, sprite2;
Texture img;
World world;
Body body, body2;
Body bodyEdgeScreen;
Matrix4 debugMatrix;
OrthographicCamera camera;
// final float PIXELS_TO_METERS = 100f;
final short PHYSICS_ENTITY = 0x1; // 0001
final short WORLD_ENTITY = 0x1 << 1; // 0010 or 0x2 in hex
@Override
public void create() {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
// Create two identical sprites slightly offset from each other vertically
sprite = new Sprite(img);
sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2 +200);
sprite2 = new Sprite(img);
sprite2.setPosition(-sprite.getWidth()/2 + 20,-sprite.getHeight()/2 + 800);
world = new World(new Vector2(0, -100f),true);
// Sprite1's Physics body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(sprite.getX() + sprite.getWidth()/2,
sprite.getY() + sprite.getHeight()/2);
body = world.createBody(bodyDef);
// Sprite2's physics body
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.DynamicBody;
bodyDef2.position.set(sprite2.getX() + sprite2.getWidth()/2,
sprite2.getY() + sprite2.getHeight()/2);
body2 = world.createBody(bodyDef2);
// Both bodies have identical shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2, sprite.getHeight()/2);
// Sprite1
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
fixtureDef.restitution = 0.5f;
fixtureDef.filter.categoryBits = PHYSICS_ENTITY;
fixtureDef.filter.maskBits = WORLD_ENTITY;
// Sprite2
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape;
fixtureDef2.density = 0.1f;
fixtureDef2.restitution = 0.5f;
fixtureDef2.filter.categoryBits = PHYSICS_ENTITY;
fixtureDef2.filter.maskBits = WORLD_ENTITY;
body.createFixture(fixtureDef);
body2.createFixture(fixtureDef2);
shape.dispose();
// Now the physics body of the bottom edge of the screen
BodyDef bodyDef3 = new BodyDef();
bodyDef3.type = BodyDef.BodyType.StaticBody;
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
bodyDef3.position.set(0, 0);
FixtureDef fixtureDef3 = new FixtureDef();
fixtureDef3.filter.categoryBits = WORLD_ENTITY;
fixtureDef3.filter.maskBits = PHYSICS_ENTITY;
EdgeShape edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,w/2,-h/2);
fixtureDef3.shape = edgeShape;
bodyEdgeScreen = world.createBody(bodyDef3);
bodyEdgeScreen.createFixture(fixtureDef3);
edgeShape.dispose();
camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
createContactListener();
}
@Override
public void render() {
camera.update();
// Step the physics simulation forward at a rate of 60hz
world.step(1f/60f, 6, 2);
sprite.setPosition((body.getPosition().x) - sprite.getWidth()/2 ,
(body.getPosition().y) -sprite.getHeight()/2 );
sprite.setRotation((float)Math.toDegrees(body2.getAngle()));
sprite2.setPosition((body2.getPosition().x) - sprite2.getWidth()/2 ,
(body2.getPosition().y) -sprite2.getHeight()/2 );
sprite2.setRotation((float)Math.toDegrees(body.getAngle()));
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(), sprite.getOriginY(),
sprite.getWidth(), sprite.getHeight(), sprite.getScaleX(), sprite.getScaleY(), sprite.getRotation());
batch.draw(sprite2, sprite2.getX(), sprite2.getY(),sprite2.getOriginX(), sprite2.getOriginY(),
sprite2.getWidth(), sprite2.getHeight(), sprite2.getScaleX(), sprite2.getScaleY(), sprite2.getRotation());
batch.end();
}
@Override
public void dispose() {
img.dispose();
world.dispose();
}
private void createContactListener() {
world.setContactListener(new ContactListener() {
@Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
Body bodyA = contact.getFixtureA().getBody();
Body bodyB = contact.getFixtureB().getBody();
Gdx.app.log("beginContact", "between " + bodyA.toString() + " and " + bodyB.toString());
}
@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
Body bodyA = contact.getFixtureA().getBody();
Body bodyB = contact.getFixtureB().getBody();
Gdx.app.log("endContact", "between " + bodyA.toString() + " and " + bodyB.toString());
}
@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
}
});
}
}
我有一个问题:为什么这段代码无法检测到两个动态物体之间的接触?它只能检测动态和静态物体之间的碰撞。
答案 0 :(得分:1)
这是预期的结果,因为您正在过滤动态实体之间的碰撞:
fixtureDef2.filter.categoryBits = PHYSICS_ENTITY;
fixtureDef2.filter.maskBits = WORLD_ENTITY;
这表示fixtureDef2
是PHYSICS_ENTITY
(categoryBits
)并且应该与WORLD_ENTITY
(maskBits
)发生冲突。
如果您希望它与PHYSICS_ENTITY
发生碰撞,则需要将maskbits
设置为PHYSICS_ENTITY | WORLD_ENTITY
。
基本上碰撞过滤是这样完成的:
boolean collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0;
在您的实际案例中,这是:
0010 & 0001 != 0 && 0001 & 0010 != 0
是false
,因此没有碰撞。
Here您可以阅读有关碰撞过滤的更多信息。