После выстрелов турели вылетает ошибка isLocked == false LibGDX

Недавно решил попробовать написать простенький Tower-Defence, чтоб турели стреляли, пули летали и т.д. (пока без плашек здоровья, обработки коллизий и прочих прелестей). Так вот, вроде бы ничего не предвещало, как начала после 3-5 секунд работы вылетать ошибка, указанная в заголовке. Вычитал, что вроде нельзя менять/обновлять физику мира после метода world.step(), попереставлял его в разные части кода (методы render, update), не помогло. Прошу помочь, т.к. сам не представляю в чём затык.

Немного поясню за код:

  1. У турели есть своя область обзора, выраженная классом Rectangle (view_zone), а также у игрока есть Rectangle, по размерам равный его телу (view_body). Когда одно накладывается на другое, турель поворачивается к игроку и стреляет каждые 1,5 секунды (спавнится пуля, затем смотри пункт 2).

  2. Пуля летит по прямой в сторону позиции игрока (метод move())

  3. Игрок двигается по прямой в сторону позиции нажатия на экран.

  4. Остальные объекты (объекты класса Building, например) не несут сложной логики и выполняют роль препяствий.

Вот мой код:

Инициализация + методы render и update

@Override
public void create () {

    float width = Gdx.graphics.getWidth()*2f;
    float height = Gdx.graphics.getHeight()*2f;

    camera = new OrthographicCamera();
    camera.setToOrtho(false,
            width,
            height);
    world = new World(new Vector2(), false);
    renderer = new Box2DDebugRenderer();
    target = new Vector3();
    buildingPlace = new Vector3();

    player = new Player(-50 , 0);

    turrets = new ArrayList<>();

    turrets.add(new Turret(128, 64));
    turrets.add(new Turret(128, 192));
    turrets.add(new Turret(350, 80));

    wall1 = new Building(0, 300, 1000, 32);
    wall2 = new Building(0, 0, 1000, 32);
}

@Override
public void render ()
{
    update(Gdx.graphics.getDeltaTime());
    ScreenUtils.clear(0, 0, 0, 0);
    world.step(1/60f, 6, 2);
    renderer.render(world, camera.combined.scl(Constants.PPM));
}

private void update(float delta)
{
    for(Turret t : turrets){
        t.checkPlayer();
    }
    handleInput();

    cameraUpdate();
}

Проверка наличия игрока в зоне видимости турелей + стрельба:

public void checkPlayer() {

    boolean seesPlayer = view_zone.overlaps(Player.view_body);
    if(seesPlayer) {
        float angle = (float) Math.atan2(player.getPosition().y - getPosition().y, player.getPosition().x - getPosition().x);
        getBody().setTransform(getPosition().x, getPosition().y, angle);
    }
    if (seesPlayer && !isTimerRunning) {
        isTimerRunning = true;
        timer.schedule(timerTask, 0, 1000);
    } else if(!seesPlayer){
        timer.cancel();
    }
}

public void shoot() {
    Bullet bullet = new Bullet(getPosition().x * Constants.PPM, getPosition().y * Constants.PPM);
    Vector2 velocity = new Vector2();
    velocity.x = MyGame.player.getBody().getPosition().x;
    velocity.y = MyGame.player.getBody().getPosition().y;
    bullet.move(velocity.cpy().sub(bullet.getPosition()).nor().scl(10));
}

Ответы (0 шт):