so habe ich ein Problem, das ich wirklich nicht verstehe. Nachdem ich versucht habe herauszufinden, was los ist, habe ich beschlossen, eine video aufzunehmen und hier zu fragen.Box2D Kollisionserkennung schlägt fehl
Behalten Sie im Video den True/False-Booleschen Wert in der linken Ecke im Auge. Das ist meine Variable canJumps Wert. Am Anfang geht der Wert zwischen wahr und falsch, nur indem man den "Player" links und rechts bewegt. Dies tritt auch auf, wenn der Spieler Steigungen und Gefälle ansteigt.
Die Karte/Kollisionsschicht wird mit Tiled erstellt.
Meine TiledObject Klasse:
public class TiledObjectUtil {
public static float PPM = 32;
public static void parseTiledObjectLayer(World world, MapObjects objects) {
for(MapObject object : objects) {
Shape shape;
if(object instanceof PolylineMapObject) {
shape = createPolyLine((PolylineMapObject) object);
} else {
continue;
}
Body body;
BodyDef bdef = new BodyDef();
bdef.type = BodyDef.BodyType.StaticBody;
body = world.createBody(bdef);
body.createFixture(shape, 1.0f);
shape.dispose();
}
}
private static ChainShape createPolyLine(PolylineMapObject polyline) {
float[] vertices = polyline.getPolyline().getTransformedVertices();
Vector2[] worldVertices = new Vector2[vertices.length/2];
for(int i = 0; i<worldVertices.length; i++) {
worldVertices[i] = new Vector2(vertices[i * 2]/PPM, vertices[i*2+1]/PPM);
}
ChainShape cs = new ChainShape();
cs.createChain(worldVertices);
return cs;
}}
Und meine Spielerklasse:
public class Player {
private BodyDef def = new BodyDef();
public Body playerBody;
private float speed = 10;
public Player() {
}
public void update() {
if (InputUtil.moveLeft) {
playerBody.setLinearVelocity(-speed, playerBody.getLinearVelocity().y);
}
if (InputUtil.moveRight) {
playerBody.setLinearVelocity(speed, playerBody.getLinearVelocity().y);
}
if (!InputUtil.moveLeft && !InputUtil.moveRight) {
playerBody.setLinearVelocity(0, playerBody.getLinearVelocity().y);
}
}
public void jump() {
if (ContactUtil.canJump) {
playerBody.applyLinearImpulse(0, 80, 0, 0, true);
}
}
public Body createPlayer(World world) {
def.type = BodyDef.BodyType.DynamicBody;
def.position.set(20, 20);
def.fixedRotation = true;
playerBody = world.createBody(def);
PolygonShape shape = new PolygonShape();
shape.setAsBox(2f/2, 2f/2);
FixtureDef playerFixture = new FixtureDef();
playerFixture.density = 1f;
playerFixture.shape = shape;
playerFixture.restitution = 0f;
playerFixture.friction = 1f;
playerBody.createFixture(playerFixture);
shape.setAsBox(2f/2, 1f/2, new Vector2(0, 0 - 1), 0);
playerFixture.shape = shape;
playerFixture.isSensor = true;
playerBody.createFixture(playerFixture).setUserData("player");
shape.dispose();
return playerBody;
} }
Und schließlich meine ContactListener:
public class ContactUtil implements ContactListener {
public static boolean canJump;
public ContactUtil() {
}
@Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
System.out.println(fixtureA.getUserData() + ", " + fixtureB.getUserData());
if (fixtureA.getUserData() == "player" && fixtureB.getUserData() == null) {
canJump = true;
}
if (fixtureA.getUserData() == null && fixtureB.getUserData() == "player") {
canJump = true;
}
}
@Override
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
System.out.println(fixtureA.getUserData() + ", " + fixtureB.getUserData());
if (fixtureA.getUserData() == "player" && fixtureB.getUserData() == null) {
canJump = false;
}
if (fixtureA.getUserData() == null && fixtureB.getUserData() == "player") {
canJump = false;
}
}
Auch meine Spieler springt ein wenig jedes Mal stoppt in einer Steigung. Ich weiß, dass es wegen dieser Linie ist: playerBody.setLinearVelocity(0, playerBody.getLinearVelocity().y);
Wenn jemand einen besseren Weg kennt, um die Bewegung zu behandeln, würde es sehr geschätzt werden.