我正在用 Libgdx 编写一个游戏。在我的游戏中,我同时创建了 5 枚火箭(使用数组)和一只鸟(玩家)。我使用 ContactListener 来检测火箭和 Bird 之间的碰撞,如下所示:
if ((BodyUtils.bodyIsBird(a) && BodyUtils.bodyIsBoom(b))
|| (BodyUtils.bodyIsBird(b) && BodyUtils.bodyIsBoom(a))) {
explosion_sound.play();
removeRocket();
}
碰撞时,我只想移除五分之一的火箭,即真正与我的鸟碰撞的火箭。我在removeRocket()中编写了这样的代码,但它删除了所有5个火箭,我不希望这样:
Array<Body> bodies = new Array<Body>(world.getBodyCount());
world.getBodies(bodies);
for (Body body : bodies) {
if (BodyUtils.bodyIsBoom(body)) {
world.destroyBody (body);
}
}
}
请帮助我!
最佳答案
使用这个循环:
Array<Body> bodies = new Array<Body>(world.getBodyCount());
world.getBodies(bodies);
for (Body body : bodies) {
if (BodyUtils.bodyIsBoom(body)) {
world.destroyBody (body);
}
}
}
您迭代世界中的所有物体并删除所有属于火箭的物体(BodyUtils.bodyIsBoom(body) 计算结果为 true)。
你永远不会指定你真正想要摧毁的 body !
只需向您的removeRocket(或removeBody)方法添加一个参数来指定要删除的主体,如下所示:
// In your contact listener
if (BodyUtils.bodyIsBird(a) && BodyUtils.bodyIsBoom(b))
{
explosion_sound.play();
removeBody(b);
}
if (BodyUtils.bodyIsBird(b) && BodyUtils.bodyIsBoom(a))
{
explosion_sound.play();
removeBody(a);
}
private final Array<Body> toBeRemovedBodies = new Array<Body>();
public void removeBody(Body body)
{
toBeRemovedBodies.add(body);
}
// After you stepped you world
for(Body body : toBeRemovedBodies)
world.destroyBody(body);
旁注:如您所见,我不会在removeBody方法中销毁主体,因为它是在世界当前处于模拟状态时调用的,并且在此期间不得销毁主体,因为它可能会导致不可预测的结果行为。
编辑:
由于再次阅读您的问题后,我不确定我是否完全理解它,这就是为什么我创建了一个关于如何在接触时摧毁 body 的小而完整的示例:
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.*;
import com.badlogic.gdx.utils.Array;
public class TestGame extends ApplicationAdapter
{
enum BodyData
{
BIRD, ROCKET;
}
class MyContactListener implements ContactListener
{
@Override
public void beginContact(Contact contact)
{
Body a = contact.getFixtureA().getBody();
Body b = contact.getFixtureB().getBody();
if (a.getUserData() == BodyData.BIRD
&& b.getUserData() == BodyData.ROCKET)
{
// play sound
toBeDeletedBodies.add(b);
}
if (b.getUserData() == BodyData.BIRD
&& a.getUserData() == BodyData.ROCKET)
{
// play sound
toBeDeletedBodies.add(a);
}
}
@Override
public void endContact(Contact contact)
{
// TODO Auto-generated method stub
}
@Override
public void preSolve(Contact contact, Manifold oldManifold)
{
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse)
{
// TODO Auto-generated method stub
}
}
Array<Body> toBeDeletedBodies = new Array<>();
Array<Body> allBodies = new Array<>();
World world;
Box2DDebugRenderer renderer;
OrthographicCamera camera;
@Override
public void create()
{
world = new World(new Vector2(0, -1), true);
BodyDef bodyDefBird = new BodyDef();
bodyDefBird.position.set(0, 0.1f);
bodyDefBird.type = BodyDef.BodyType.DynamicBody;
BodyDef bodyDefRocket1 = new BodyDef();
bodyDefRocket1.position.set(0, 0.5f);
bodyDefRocket1.type = BodyDef.BodyType.DynamicBody;
BodyDef bodyDefRocket2 = new BodyDef();
bodyDefRocket2.position.set(0.1f, 0.8f);
bodyDefRocket2.type = BodyDef.BodyType.DynamicBody;
FixtureDef circleFixture = new FixtureDef();
circleFixture.shape = new CircleShape();
((CircleShape) circleFixture.shape).setRadius(0.02f);
FixtureDef rocketFixture = new FixtureDef();
rocketFixture.shape = new PolygonShape();
((PolygonShape) rocketFixture.shape).set(new float[]
{ 0, 0, 0.01f, 0, 0.01f, 0.05f, 0, 0.05f, 0, 0 });
BodyDef bodyDefFloor = new BodyDef();
bodyDefFloor.position.set(-100, 0);
bodyDefFloor.type = BodyDef.BodyType.StaticBody;
FixtureDef lineFixture = new FixtureDef();
lineFixture.shape = new EdgeShape();
((EdgeShape) lineFixture.shape).set(Vector2.Zero, new Vector2(200, 0));
Body floor = world.createBody(bodyDefFloor);
floor.createFixture(lineFixture);
Body bird = world.createBody(bodyDefBird);
bird.createFixture(circleFixture);
bird.setUserData(BodyData.BIRD);
Body rocket1 = world.createBody(bodyDefRocket1);
rocket1.createFixture(rocketFixture);
rocket1.setUserData(BodyData.ROCKET);
Body rocket2 = world.createBody(bodyDefRocket2);
rocket2.createFixture(rocketFixture);
rocket2.setUserData(BodyData.ROCKET);
renderer = new Box2DDebugRenderer();
camera = new OrthographicCamera();
world.setContactListener(new MyContactListener());
rocketFixture.shape.dispose();
circleFixture.shape.dispose();
lineFixture.shape.dispose();
}
@Override
public void render()
{
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1 / 60f, 8, 3);
renderer.render(world, camera.combined);
for (Body body : toBeDeletedBodies)
{
world.destroyBody(body);
}
toBeDeletedBodies.clear();
}
@Override
public void dispose()
{
renderer.dispose();
world.dispose();
}
}
当您运行此示例时,您会看到地板上有一个圆圈(鸟)和两个掉落的矩形(火箭)。其中一个矩形击中圆并因此被破坏,另一个矩形没有被破坏。
关于java - 如何在碰撞时仅删除数组中的一个 Body? Libgdx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33063231/