我使用此方法处理弹性碰撞(使用this作为来源):
public static void handleElasticCollisions(Entity a, Entity b) {
// make a few variables to make equations easier to read
Vector2f aPos = a.getPos();
Vector2f bPos = b.getPos();
Vector2f aV = a.getVelocity();
Vector2f bV = b.getVelocity();
float aMass = a.getSize();
float bMass = b.getSize();
// find unit normal vector
Vector2f uN = normalize(Vector2f.sub(bPos, aPos));
// find unit tanget vector
Vector2f uT = new Vector2f(-uN.y, uN.x);
// get normal and tangential components of both velocity vectors
// before the collision
float aVn = dot(uN, aV);
float aVt = dot(uT, aV);
float bVn = dot(uN, bV);
float bVt = dot(uT, bV);
// get normal and tangential components of both velocity vectors
// after the collision
float aVN = (aVn*(aMass - bMass) + 2*bMass*bVn)/(aMass + bMass);
float aVT = aVt;
float bVN = (bVn*(bMass - aMass) + 2*aMass*aVn)/(aMass + bMass);
float bVT = bVt;
// convert normal and tangential components into vectors
Vector2f avn = Vector2f.mul(uN, aVN);
Vector2f avt = Vector2f.mul(uT, aVT);
Vector2f bvn = Vector2f.mul(uN, bVN);
Vector2f bvt = Vector2f.mul(uT, bVT);
a.setVelocity(Vector2f.add(avn, avt));
b.setVelocity(Vector2f.add(bvn, bvt));
}
然而,有时候,实体彼此进入/彼此粘在一起而不是彼此反弹。 这是我的更新方法,仅包含相关代码:
public void show() {
// set delta time
float currentTime = clock.getElapsedTime().asSeconds();
float dt = currentTime - lastTime;
// update entities and check for removal
for (Entity e : entities) {
e.update(dt);
}
// draw entities
for (Entity e : entities) {
e.draw();
}
Window.getWindow().draw(pointerSprite);
Window.getWindow().display();
lastTime = currentTime;
}
在我的碰撞实体的update
中,我检查了一下:
public boolean intersectsWithAsteroid() {
for (Entity e : GameScreen.getEntities()) {
if (e instanceof AsteroidEntity &&
asteroidSprite.getGlobalBounds().intersection(e.getBounds()) != null &&
!this.equals(e)) {
collidingAsteroid = (AsteroidEntity)e;
return true;
}
}
return false;
}
public void handleAsteroidIntersection() {
CMath.handleElasticCollisions(this, collidingAsteroid);
}
Here是intersection
的文档。
我不明白为什么会发生这种情况,有人能告诉我我是如何实施这种算法的吗?
答案 0 :(得分:0)
所以,我最后修改了它,将这3行代码添加到我的响应函数中:
Vector2f rv = Vector2f.sub(bV, aV);
Vector2f norm = Vector2f.sub(bPos, aPos);
float velAlongNormal = CMath.dot(rv, norm);
// Do not resolve if velocities are separating
if(velAlongNormal > 0) {
return;
}
如果物体的速度没有直接碰撞,那么就不应该有碰撞响应。这解决了所有问题。