Способ решения этой проблемы заключается в создании класса, который реализует ContactListener, а затем, когда вы создаете World, вы .setContactListener () для своего класса.Теперь ваш класс будет уведомлен обо всех столкновениях.Оттуда вы создаете флаг, если игрок контактирует с какими-либо наземными объектами.
Предположим, что вы установили userData фигур для соответствующих GameObjects (shapeDef.userData = this;
в конструкторе GameObject).Предположим, у вас есть enum, который определяет типы GameObject в вашей игре, а затем у вас есть контактный слушатель по следующим направлениям:
import org.jbox2d.dynamics.ContactListener;
import org.jbox2d.dynamics.contacts.ContactPoint;
import org.jbox2d.dynamics.contacts.ContactResult;
import android.util.Log;
import GameObject.GAME_OBJECT_TYPE;
public class CollisionChecker implements ContactListener {
private boolean groundCollision = false;
@Override
public void add(ContactPoint arg0) {
// Called when a contact point is added. This includes the geometry and the forces.
}
@Override
public void persist(ContactPoint arg0) {
// Called when a contact point persists. This includes the geometry and the forces.
}
@Override
public void remove(ContactPoint arg0) {
// Called when a contact point is removed. This includes the last computed geometry and forces.
}
@Override
public void result(ContactResult arg0) {
// This is called once the collision has been resolved
GAME_OBJECT_TYPE a = ((GameObject) arg0.shape1.getUserData()).getType();
GAME_OBJECT_TYPE b = ((GameObject) arg0.shape2.getUserData()).getType();
//check for ground
groundCollision = check(a, b, GAME_OBJECT_TYPE.ground);
}
private boolean check(GAME_OBJECT_TYPE a, GAME_OBJECT_TYPE b, GAME_OBJECT_TYPE test){
if (a == test && b == GAME_OBJECT_TYPE.player){
return true;
}
else if (a == GAME_OBJECT_TYPE.player && b == test){
return true;
}
return false;
}
public boolean isGroundCollision(){
return groundCollision;
}
public void step() {
/*
if (groundCollision)
Log.d("COLLSN", "We have a collision with ground");*/
//after logic, reset the state variables
reset();
}
private void reset(){
groundCollision = false;
}
}
Теперь вы создаете логический переход в вашем плеере.Когда он прыгает, установите его в true.Он больше не может прыгать, когда флаг верен.Проверьте каждый кадр на столкновение с землей с помощью collisionChecker.isGroundCollision ().Когда происходит столкновение, снова установите player.jump = false.
Здесь есть проблема, заключающаяся в том, что если у вас вертикальное основание, игрок сможет прыгнуть через стену.Если игрок ударит его головой о землю, он также сможет прыгать больше.Для решения этих проблем вы проверяете «arg0.position», чтобы узнать, где была точка контакта относительно объекта игрока.Если контакт не находится под игроком, то он бьет себя по голове или бьет по стене.