C# Monogame и Farseer Physics: столкновения

Я начинающий. Я использую библиотеку Monogame и Farseer Physics Library на С#. (последние версии)

В моей игре всякий раз, когда мой ball (круг) сталкивается с corner of a rectangle (или даже с другим кругом), предполагается, что он меняет направление только по оси Y.

Однако он не только меняет направление по оси Y (как и предполагалось), но также немного перемещается вправо (или влево соответственно), в зависимости от того, как вы попали в угол (или другой круг). . Как будто на мяч действует какая-то сила, заставляющая его двигаться и по оси X.

http://i.imgur.com/rEbNTua.png?1

Это движение классное и все такое, и оно имеет большой смысл, но в моей игре его нет, поэтому я хочу избавиться от него.

Как это возможно ? Я предполагаю, что мне нужно изменить некоторые значения по умолчанию.

Вот как выглядит моя кодировка:

BallBody.BodyType = BodyType.Dynamic;
BlockBody.BodyType = BodyType.Static;
Ball.LinearVelocity = new Vector(0,-1); // ball going up
BallBody.OnCollision += Ball_OnCollision;

public bool Ball_OnCollision(Fixture f1, Fixture f2, Contact contact)
{
    // if the Ball (f1), collides with the Block (f2)
    if (f2.Body == BlockBody)
    // change the direction of the Ball on Y-Axis
    Ball.LinearVelocity = new Vector(0,-1);
    return true;
}

Также при высоких скоростях это происходит:

введите здесь описание изображения

Несмотря на то, что мяч никогда не может пройти через блок (туннелирование), я хочу знать, как я могу это исправить, чтобы мяч никогда не попадал в зону блока?


person dimitris93    schedule 28.11.2014    source источник


Ответы (1)


К сожалению, это на удивление сложно сделать с Box2D. Лучшее, что я мог сделать, когда пытался, - это записать скорость мяча в начале контакта, а затем, когда контакт закончился, вручную установить желаемую скорость. Это прекрасно работает, когда мяч начинает и заканчивает контакт только с одним блоком за раз, но в некоторых случаях мяч может начать касаться двух блоков за один и тот же временной шаг. Вам нужно было бы посмотреть на расположение блоков, которых он коснулся, и рассчитать для себя, под каким углом вы ожидаете, что он отскочит. В конце концов я просто сдался и не стал освещать это дело.

person iforce2d    schedule 28.11.2014
comment
для мяча должно быть невозможно коснуться двух прямоугольников одновременно, потому что круг касается нижней стороны прямоугольника с точностью до 1 пикселя, а 2 прямоугольника никогда не находятся в одном и том же пикселе одновременно, верно? - person dimitris93; 28.11.2014
comment
Я хочу знать ЗАРАНЕЕ, когда произойдет столкновение (на 1 кадр раньше), поэтому мне нужна функция OneFrameBeforeCollision, а не OnCollision, я думаю? как я могу реализовать что-то подобное? Есть некоторые свойства Body.CollisionCategories (Categorie.Cat1, Categorie.Cat2,..., Categorie.Cat31). Знаете ли вы, может быть, некоторые из этих 31 делают то, что я ищу, проще? Я не могу найти документацию для них. Я даже не знаю, что они делают и помогают ли они моему делу каким-либо образом. - person dimitris93; 28.11.2014
comment
Мяч может легко коснуться двух блоков одновременно, если он попадает в место, где два блока касаются друг друга, и он перекрывает их оба. К сожалению, в Box2D невозможна предварительная проверка, так как это не имеет смысла - как физический движок может знать, приложишь ли ты силу перед следующим временным шагом и изменишь направление чего-либо... - person iforce2d; 28.11.2014
comment
два блока касаются друг друга, хотя мои блоки никогда не касаются друг друга, не так ли? каждый блок начинается в конце другого я думаю - person dimitris93; 28.11.2014
comment
Ну, даже если между ними есть зазор, вы все равно можете разместить круг так, чтобы он перекрывал два блока одновременно, верно? - person iforce2d; 29.11.2014
comment
я думаю, вы правы, я должен сделать это вручную, чтобы он попадал только в 1 блок за раз, потому что я не хочу, чтобы он попадал во 2, хотя я добился огромного прогресса, большое спасибо - person dimitris93; 29.11.2014