我尝试与StaticBody一起拍摄碰撞时删除/删除此身体
if ((fixtureB == obstacleFixture) && (fixtureA == shootFixture)) {
// destroy();
obstacleBody.destroyFixture(obstacleFixture);
}
但是在这部分代码中,当有联系时,所有应用程序崩溃,并且不知道原因。
File: /var/lib/jenkins/workspace/libgdx/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Dynamics/b2Body.cpp, Line 216
Expression: m_world->IsLocked() == false
实际上,我对这个库有点迷失,使它基本上创建了一个三角形和一个矩形,当你点击,拍摄时,现在当镜头与三角形碰撞时,三角形必须消失。但直接跨越APP崩溃
public class Box2DScreen extends MyScreenAdapter {
private World world;
private Box2DDebugRenderer renderer;
private OrthographicCamera camara;
private Body playerBody;
private Fixture playerFixture;
private Body shootBody;
private Fixture shootFixture;
private Body floorBody;
private Fixture floorFixture;
private Body obstacleBody;
private Fixture obstacleFixture;
private boolean mustJump = false;
private boolean isShooting = false;
private boolean jumping = false;
private boolean shooting = false;
private boolean playerLive = true;
public Box2DScreen(MainGame game) {
super(game);
}
@Override
public void show() {
world = new World(new Vector2(0, -10), true);
renderer = new Box2DDebugRenderer();
camara = new OrthographicCamera(16.00f, 9.00f);
camara.translate(0, 1);
world.setContactListener(new ContactListener() {
@Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
if ((fixtureA.getUserData().equals("player")) && (fixtureB.getUserData().equals("floor"))) {
if (Gdx.input.isTouched()) {
mustJump = true;
}
jumping = false;
}
if ((fixtureA.getUserData().equals("floor")) && (fixtureB.getUserData().equals("player"))) {
if (Gdx.input.isTouched()) {
mustJump = true;
}
jumping = false;
}
if ((fixtureA.getUserData().equals("player")) && (fixtureB.getUserData().equals("obstacle"))) {
if (Gdx.input.isTouched()) {
playerLive = false;
}
}
if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("player"))) {
if (Gdx.input.isTouched()) {
playerLive = false;
}
}
if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("shoot"))) {
//destroy();
obstacleBody.destroyFixture(obstacleFixture);
}
}
@Override
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
if ((fixtureA == playerFixture) && (fixtureB == floorFixture)) {
jumping = true;
}
if ((fixtureB == playerFixture) && (fixtureA == floorFixture)) {
jumping = true;
}
if ((fixtureA == shootFixture) && (fixtureB == obstacleFixture)) {
// destroy();
}
if ((fixtureB == obstacleFixture) && (fixtureA == shootFixture)) {
// destroy();
}
}
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
}
});
BodyDef playerBodyDef;
playerBodyDef = createPlayerBodyDef();
playerBody = world.createBody(playerBodyDef);
PolygonShape playerShape = new PolygonShape();
playerShape.setAsBox(0.5f, 0.5f);
playerFixture = playerBody.createFixture(playerShape, 1);
playerShape.dispose();
BodyDef floorBodyDef;
floorBodyDef = createFloorBodyDef();
floorBody = world.createBody(floorBodyDef);
PolygonShape floorShape = new PolygonShape();
floorShape.setAsBox(500.00f, 1.00f);
floorFixture = floorBody.createFixture(floorShape, 1);
floorShape.dispose();
BodyDef obstacleBodyDef;
obstacleBodyDef = createObstacleBodyDef(6f);
obstacleBody = world.createBody(obstacleBodyDef);
obstacleFixture = createObstacleFixture(obstacleBody);
playerFixture.setUserData("player");
floorFixture.setUserData("floor");
obstacleFixture.setUserData("obstacle");
}
private BodyDef createShootBodyDef() {
BodyDef def = new BodyDef();
def.position.set(playerBody.getPosition().x + 1f, playerBody.getPosition().y);
def.type = BodyDef.BodyType.DynamicBody;
def.gravityScale = 0;
return def;
}
private Fixture createObstacleFixture(Body obstacle) {
Vector2[] vertices = new Vector2[3];
vertices[0] = new Vector2(-0.5f, -0.5f);
vertices[1] = new Vector2(0.5f, -0.5f);
vertices[2] = new Vector2(0, 0.5f);
PolygonShape shape = new PolygonShape();
shape.set(vertices);
Fixture fix = obstacle.createFixture(shape, 1);
shape.dispose();
return fix;
}
private BodyDef createObstacleBodyDef(float x) {
BodyDef def = new BodyDef();
def.position.set(x, 0.5f);
def.type = BodyDef.BodyType.StaticBody;
return def;
}
private BodyDef createPlayerBodyDef() {
BodyDef def = new BodyDef();
def.position.set(0, 0.5f);
def.type = BodyDef.BodyType.DynamicBody;
return def;
}
private BodyDef createFloorBodyDef() {
BodyDef def = new BodyDef();
def.position.set(0, -1);
def.type = BodyDef.BodyType.StaticBody;
return def;
}
@Override
public void dispose() {
playerBody.destroyFixture(playerFixture);
floorBody.destroyFixture(floorFixture);
obstacleBody.destroyFixture(obstacleFixture);
shootBody.destroyFixture(shootFixture);
world.destroyBody(playerBody);
world.destroyBody(floorBody);
world.destroyBody(obstacleBody);
world.destroyBody(shootBody);
world.dispose();
renderer.dispose();
}
@Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (mustJump) {
mustJump = false;
saltar();
}
if (Gdx.input.justTouched() && !jumping) {
mustJump = true;
}
if (Gdx.input.justTouched() && shooting) {
destroy();
}
if (Gdx.input.justTouched() && !shooting) {
BodyDef shootBodyDef;
shootBodyDef = createShootBodyDef();
shootBody = world.createBody(shootBodyDef);
PolygonShape shootShape = new PolygonShape();
shootShape.setAsBox(0.3f, 0.09f);
shootFixture = shootBody.createFixture(shootShape, 1);
shootShape.dispose();
shootFixture.setUserData("shoot");
shooting = true;
}
if (shooting) {
float velocidadY = shootBody.getLinearVelocity().y;
shootBody.setLinearVelocity(6, velocidadY);
}
if (playerLive) {
float velocidadY = playerBody.getLinearVelocity().y;
playerBody.setLinearVelocity((float) 0.7, velocidadY);
}
world.step(delta, 6, 2);
camara.update();
renderer.render(world, camara.combined);
}
private void saltar() {
Vector2 position = playerBody.getPosition();
playerBody.applyLinearImpulse(0, 6, position.x, position.y, true);
}
private void destroy(){
shooting = false;
shootBody.destroyFixture(shootFixture);
world.destroyBody(shootBody);
}
}
答案 0 :(得分:1)
你不能在碰撞时移除身体,box2d正在进行数学计算,如果你将其删除就会疯狂,最好的方法是设置setActive(false)并在以后的迭代中删除它你的渲染方法,如下所示:
[...]
private List<Fixture> lstRemoveFixture = new ArrayList<>();
[...]
@Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
if(fixtureA != null and fixtureB != null){
[...]
if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("shoot"))) {
//destroy();
obstacleBody.setActive(false);
lstRemoveFixture.add(obstacleFixture);
}
}
}
在你的渲染方法上:
public void render(float delta) {
[...]
world.step(delta, 6, 2);
for(Fixture fixture : lstRemoveFixture){
obstacleBody.destroyFixture(fixture);
lstRemoveFixture.remove(fixture);
}
obstacleBody.setActive(true);
[...]
}