[英]How to remove just one Body exactly in array when collision? Libgdx
我正在用Libgdx编写游戏。 在我的游戏中,我同时创造了5枚火箭(使用Array)和一个Bird(玩家)。 我使用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)。
您永远不会指定您实际要销毁的尸体!
只需将参数添加到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方法上破坏物体,因为它是在当前世界处于仿真状态时调用的,并且在此期间不得破坏物体,因为它可能导致不可预测的行为。
编辑:
由于在再次阅读您的问题后,我不能完全确定自己是否完全理解它,因此,我创建了一个小而完整的示例来说明如何在接触时破坏尸体:
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();
}
}
运行此示例时,您会看到地板上有一个圆圈(鸟)和两个矩形(火箭)掉落的情况。 一个矩形碰到圆并因此被破坏,另一个矩形不被破坏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.