本章源码链接:Libgdx重建FlappyBird密码:twy2
上一章完整的介绍了BOX2D的物理仿真创建过程,在本章我们将继续完成BOX2D的剩余内容——碰撞检测。因为BOX2D帮我们完成了所有物理模拟过程,包括碰撞检测,这极大的降低我们的项目难度,我们不需要理解碰撞检测如何运行,甚至不需要知道任何碰撞检测算法,就能够完成碰撞检测并通知我们。下面就让我们为FlappyBird添加碰撞检测的回调函数和相应的逻辑代码。
上一章完整的介绍了BOX2D的物理仿真创建过程,在本章我们将继续完成BOX2D的剩余内容——碰撞检测。因为BOX2D帮我们完成了所有物理模拟过程,包括碰撞检测,这极大的降低我们的项目难度,我们不需要理解碰撞检测如何运行,甚至不需要知道任何碰撞检测算法,就能够完成碰撞检测并通知我们。下面就让我们为FlappyBird添加碰撞检测的回调函数和相应的逻辑代码。
碰撞检测
打开WorldController类,并为其添加下面代码:
...
public class WorldController extends InputAdapter implements Disposable {
...
private void initWorld() {
if(world != null) world.dispose();
world = new World(new Vector2(0, -110.8f), false);
// 为world添加碰撞检测监听器
world.setContactListener(new BirdContactListener());
}
...
private void collisionDetection(AbstractGameObject a, AbstractGameObject b) {
}
// 碰撞检测监听器
private class BirdContactListener implements ContactListener {
@Override public void beginContact(Contact arg0) {
AbstractGameObject a = (AbstractGameObject)arg0.getFixtureA().getBody().getUserData();
AbstractGameObject b = (AbstractGameObject)arg0.getFixtureB().getBody().getUserData();
collisionDetection(a, b);
}
@Override public void endContact(Contact arg0) {}
@Override public void postSolve(Contact arg0, ContactImpulse arg1) {}
@Override public void preSolve(Contact arg0, Manifold arg1) {}
}
}
首先定义一个BirdContactListener类,该类实现了ContactListener接口的四个方法,beginContact()和endContact()分别在开始碰撞(重叠)和结束碰撞时调用。preSolve()方法在碰撞检测之后,解决碰撞之前调用,你可以实现该方法替代BOX2D内置的碰撞处理方式;最后一个postSolve()方法在碰撞发生后调用,该方法是获得碰撞冲量的地方。这里只使用了一个方法beginContact(),该方法内首先通过Contact获得两个碰撞对象的Fiture然后再获得Body对象,因为创建Body时调用setUserData()方法将游戏对象本身作为用户数据,所有这里我们便可直接通过getUserData()获得游戏对象。最后调用WorldController()私有方法collisionDetection()处理碰撞事件。
在初始化函数init()中创建了一个BirdContactListener对象并调用World.setContactListener()为world设置了碰撞监听器。
根据上述添加的代码可以推断,一旦发生碰撞,collisionDetection()方法就会被调用,现在我们需要考虑在collisionDetection做什么?我们知道,FlappyBird游戏非常简单,一旦发生碰撞,游戏就即将