Box2d setAngularVelocity не работают на высоких скоростях

Я использую Box2d для игры, и хотя я использую большие константы для установки угловой скорости, самая высокая скорость, которую я могу получить, составляет 1 оборот за 3,86 секунды.

Я проверил свой исходный код в следующем потоке, и все совпадает с тем, что мне предлагали как пользователи здесь, так и в учебниках:

setAngularVelocity вращается очень медленно

Однако я заметил следующую нерешенную ветку: http://www.reddit.com/r/libgdx/comments/1qr2m3/the_strangest_libgdxbox2d_behaviour/

и заметил, что это может быть проблемой. Вот мой метод утилизации

    public void dispose() {
    //Get Rid of Everything!
    Assets.Clear();
    GameEngine.Clear();
    BallMap.clear();
    PlayerMap.clear();
    shapeRenderer.dispose();
    debugRenderer.dispose();
    world.dispose();
    batch.dispose();
    font.dispose();
}

Все они повторно инициализируются в начале следующим образом:

    this.game       = game;
    this.cameraWidth = cameraWidth*pixelRatio;
    this.cameraHeight = cameraHeight*pixelRatio;

    batch           = new SpriteBatch();
    shapeRenderer   = new ShapeRenderer();
    stateTime       = 0F;
    Scores          = new Integer[]{0, 0};

    debugRenderer   = new Box2DDebugRenderer();
    world           = new World(new Vector2(0, 0), true);   //Create a world with no gravity
    GameEngine.setContactListener(world);

Я перемещаюсь по экранам с помощью следующего кода:

    public void create () {
    scene_menu = new MainMenuScreen(this, cameraWidth, cameraHeight);
    setScreen(scene_menu);
}

public void swtogame(){
    scene_menu.dispose();
    scene_game = new MatchScreen(this, cameraWidth, cameraHeight);
    setScreen(scene_game);
}

public void swtomenu(){
    scene_game.dispose();
    scene_menu = new MainMenuScreen(this, cameraWidth, cameraHeight);
    setScreen(scene_menu);
}

как я инициализирую объекты:

public Object(World world, short category, short mask, float x, float y, float radius, Sprite image, 
    float maxSpeed, float frictionStrength, float linearDamping, float angularDamping, boolean movable,
    float elasticity, float mass){

this.world = world; 
this.category = category;
this.mask = mask;
// We set our body type
this.bodyDef = new BodyDef();
if(movable==true){bodyDef.type = BodyType.DynamicBody;}else{bodyDef.type = BodyType.StaticBody;}
// Set body's starting position in the world
bodyDef.position.set(x, y);
bodyDef.linearDamping = linearDamping;
bodyDef.angularDamping = angularDamping;
// Create our body in the world using our body definition
this.body = world.createBody(bodyDef);
// Create a circle shape and set its radius
CircleShape circle = new CircleShape();
circle.setRadius(radius);
// Create a fixture definition to apply our shape to
fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.density = (float) (mass/(Math.PI*radius*radius)); 
fixtureDef.friction = frictionStrength;
fixtureDef.restitution = elasticity;
fixtureDef.filter.categoryBits = category;
fixtureDef.filter.maskBits = mask;
// Create our fixture and attach it to the body
this.fixture = body.createFixture(fixtureDef);
// BodyDef and FixtureDef don't need disposing, but shapes do.
circle.dispose();

... unrelated functions after that
}

Правильно ли я распоряжаюсь? Это ошибка? Есть ли способ обойти это и правильно использовать setAngularVelocity?


person ozgeneral    schedule 25.02.2015    source источник
comment
Где код, которым вы задали вращение? А что происходит, когда вы превышаете 1 оборот за 3,86 секунды?   -  person weston    schedule 26.02.2015
comment
Просто не превышает 1 об/мин за 3,86 секунды, я использую object.body.setAngularVelocity(5000); или object.body.setAngularVelocity(1000); и это не имеет значения. Только когда я устанавливаю его на что-то меньшее, например 5, он вращается даже медленнее, чем 1 оборот за 3,86 секунды.   -  person ozgeneral    schedule 26.02.2015


Ответы (2)


Поскольку вы не показали много кода, я не уверен на 100%, что я прав, но я думаю, что вы достигаете встроенного максимального ограничения движения в 2,0 единицы за временной шаг. . Это означает, что при типичной частоте кадров 60 Гц тело, покрывающее 2 единицы за временной шаг, движется со скоростью 120 м/с или 432 км/ч (270 миль/ч). К сожалению, кажется, что нет прямого способа изменить это ограничение в Java, потому что это ограничение, по-видимому, определено в родных библиотеках C++.

Но я думаю, что настоящая проблема в том, что у вас неправильный масштаб. Box2D использует MKS (метры, килограммы и секунды). И, возможно, вы использовали пиксели вместо метров. FAQ Box2D предлагает использовать

объекты [которые находятся] между 0,1 - 10 метрами

иначе можно получить странные ситуации.

См. http://www.iforce2d.net/b2dtut/gotchas#speedlimit и https://code.google.com/p/box2d/wiki/FAQ

person intrigus    schedule 25.02.2015
comment
Я уже использую преобразование пикселей в метры, и изменение этого соотношения не помогает, что имеет смысл, потому что моя проблема связана не с линейным смещением, а с вращением. Большая часть исходного кода находится в первом потоке, который я опубликовал, и я использую тот же код, который другие люди проверили для работы над своим приложением. Так что что-то еще должно взаимодействовать с box2d. Из-за второго сообщения, которым я поделился, я подумал, что это может быть способ, которым я распоряжаюсь вещами или чем-то связанным, но я не уверен, что это единственная подсказка, которая у меня есть. Я могу поделиться какой-либо конкретной частью моего кода, если это поможет? - person ozgeneral; 26.02.2015

Я только что нашел проблему, и это было довольно просто. Я просто собираюсь опубликовать это здесь для будущих пользователей Google:

Объект на самом деле вращался правильно, проблема была в моем методе рисования, я не использовал преобразование между радианами в градусы в моем пакете.draw, и он интерпретировал все в радианах. Я знаю такую ​​дилетантскую ошибку! Большое спасибо за ваше время.

person ozgeneral    schedule 26.02.2015