【问题标题】:Box2D recreating a bodyBox2D 重建身体
【发布时间】:2015-04-28 11:45:25
【问题描述】:

在我的游戏中,我有一个Bullet 类,它负责在每次开枪时制造一颗新子弹。创建后,项目符号被添加到 Bullets 类中,该类负责跟踪所述项目符号以及其余项目符号。我遇到了一个奇怪的行为:
杀死一个敌人,然后再次射击后,新子弹具有以下特性:

  1. 项目符号与项目符号相同(在相同的代码 id 中) 杀死了敌人。 (即如果 id 是: com.badlogic.gdx.physics.box2d.Body@fc7157f,那么它将是 完全相同的 ID。)
  2. 子弹会出现卡在原地,它的精灵没有移动,但根据游戏它会有一个速度,但位置保持不变。唯一可见的运动是当您启用Box2DDebugRenderer 时,您可以看到身体向下移动,直到触地,此时他“传送”回来并慢慢落下。
  3. 被卡住的子弹数量等于被杀死的敌人数量。

这是子弹类:

public class Bullet {

private Body bullet;

public Bullet(final float force, final int bulletDmg, final Weapon weapon,
        final World world) {
    System.out.println("Position " + weapon.getPosition() + ", Angle: "
            + weapon.getAngle());
    final BodyDef bulletDef = new BodyDef();
    bulletDef.type = BodyDef.BodyType.DynamicBody;
    bulletDef.angle = weapon.getAngle();
    bulletDef.position.set(
            weapon.getPosition().x
                    + (float) (2.5 * MathUtils.cos(weapon.getAngle())),
            weapon.getPosition().y
                    + (float) (2.5 * MathUtils.sin(weapon.getAngle())));
    bulletDef.angle = weapon.getAngle();
    PolygonShape bulletShape_1 = new PolygonShape();
    bulletShape_1.setAsBox(0.34375f, 0.34375f);
    CircleShape bulletShape_2 = new CircleShape();
    bulletShape_2.setPosition(new Vector2(0.34375f, 0));
    bulletShape_2.setRadius(0.34375f);
    final FixtureDef bulletFixture_1 = new FixtureDef();
    bulletFixture_1.density = 1f;
    bulletFixture_1.shape = bulletShape_1;
    bulletFixture_1.friction = 0.25f;
    bulletFixture_1.restitution = 0.75f;
    final FixtureDef bulletFixture_2 = new FixtureDef();
    bulletFixture_2.density = 1;
    bulletFixture_2.shape = bulletShape_2;
    bulletFixture_2.friction = 0.25f;
    bulletFixture_2.restitution = 0.75f;
    final Timer creationTimer = new Timer();
    creationTimer.scheduleTask(new Task() {

        @Override
        public void run() {
            if (!world.isLocked()) {
                System.out.println(bullet);
                bullet = world.createBody(bulletDef);
                bullet.createFixture(bulletFixture_1);
                bullet.createFixture(bulletFixture_2);
                System.out.println(bullet);
                bullet.applyForceToCenter(
                        force * MathUtils.cos(weapon.getAngle()), force
                                * MathUtils.sin(weapon.getAngle()), true);
                Sprite sprite = new Sprite(new Texture(
                        "sprites\\Weapon\\bullet_standard.png"));
                sprite.setSize(1.03125f, 0.6875f);
                sprite.setOrigin((float) (sprite.getWidth() / 2 - 0.12f),
                        (float) (sprite.getHeight() / 2));
                bullet.setUserData(sprite);
                Bullets bullets = Bullets.getInstance(world);
                bullets.addBullet(bullet);
                bullets.setDmg(bulletDmg);
                System.out.println("Create bullet number: " + bullet);
                creationTimer.stop();
            }
        }

    }, 0, 1);
    creationTimer.start();
}

}

我已经面对这个问题已经有一段时间了,无法弄清楚问题所在,我希望得到一些帮助。提前致谢!


更新 1:
我不会重复使用任何创建的子弹。
这是处理与敌人碰撞的代码:

public void onCollision(final Body collidedBody, final String bodyHit,
        final int index) {
    assert instance != null;
    final Timer timer = new Timer();
    timer.scheduleTask(new Task() {
        @Override
        public void run() {
            if (!world.isLocked()) {
                Circles circles = Circles.getInstance();
                if (bodyHit.equalsIgnoreCase("ground")) {
                    if (bulletGroundCollision.get(index) == 5) {
                        if (bullets.get(index) != null) {
                            world.destroyBody(bullets.get(index));
                            bullets.removeIndex(index);
                            bulletGroundCollision.removeIndex(index);
                        }
                    } else
                        bulletGroundCollision.set(index,
                                (bulletGroundCollision.get(index) + 1));
                } else if (bodyHit.equalsIgnoreCase("enemy")) {
                    Circle enemy = circles
                            .findAccordingToCode(collidedBody);
                    enemy.damaged(bulletDmg);
                    System.out.println("Hit at: "
                            + bullets.get(index).getPosition());
                    if (bullets.get(index) != null) {
                        world.destroyBody(bullets.get(index));
                        bullets.removeIndex(index);
                        bulletGroundCollision.removeIndex(index);
                    }
                } else if (bodyHit.equalsIgnoreCase("player")) {
                    if (bullets.get(index) != null) {
                        world.destroyBody(bullets.get(index));
                        bullets.removeIndex(index);
                        bulletGroundCollision.removeIndex(index);
                    }
                    Square square = Square.getInstance(world);
                    square.damaged(bulletDmg);
                }
                timer.stop();
            }
        }

    }, 0, 1);
    timer.start();
}

创建子弹的代码已发布为 bullet 类。
bullets - 是子弹体的 Array
bulletGroundCollision - 是 Array用于跟踪子弹在 i 位置(即索引)击中地面的次数。

更新 2
我注意到子弹被卡住后,与子弹的碰撞不会根据身体发生,而是只有在与精灵发生碰撞时才会触发碰撞。

【问题讨论】:

  • 您是否使用Bullets 类来重用Bullets?另外,请显示处理 Bullet 何时击中敌人以及何时创建 Bullet 的代码。
  • 我编辑了帖子,when a bullet` 的代码是bullet 类。
  • @RedDeadRedemption,您究竟是如何检测碰撞的?你为此使用 Box2D 吗?我问是因为您提到了枪管和“精灵”之间的碰撞。 Box2D 肯定不知道这一点。
  • 另外,你能创建一个SSCCE吗?
  • 我正在使用 box2D 进行碰撞检测。

标签: java libgdx box2d


【解决方案1】:

您的代码有点难以阅读。但是你需要确保在你的敌人死后,你需要用你的子弹类中的更新方法再次更新你的子弹类。

boolean enemyDead;

if(damage<=0)
{
 bulletClass.updateBulletLocation();
}

在我看来,您在杀死敌人后正在更新子弹类,因此,子弹会停留在原处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多