Мяч проходит через ракетку под определенным углом

Я создаю клон понга для школы с C ++ и SFML 2.1, и у меня возникла небольшая проблема, когда мяч ударяется о левую ракетку под острым углом (он проходит).

Правая лопатка отлично работает под любым углом, и, насколько я помню, они используют один и тот же код.

Это код, который я использую для столкновения:

    for (auto& it : collisionPaddles)
    {
        if (this->ballShape.getGlobalBounds().intersects(it->getGlobalPaddleBounds()))
        {
            float deltaDistance = (this->y + this->radius) - (it->y + it->height / 2);
            bool fromLeft = true;

            if ((ballAngle < (3*myMath::MY_PI/2) && ballAngle > myMath::MY_PI/2))
            {
                fromLeft = false;
            }
            else
            {
                fromLeft = true;
            }

            ballAngle = static_cast<float>(deltaDistance * (myMath::MY_PI/180));

            if (fromLeft)
            {
                ballAngle = static_cast<float>(myMath::MY_PI - ballAngle);
            }
            moveBall(2);
        }
    }

person Jonas Natten    schedule 23.09.2014    source источник
comment
Можете ли вы уточнить свою проблему, вы обнаруживаете столкновение с веслом? что вы имеете в виду под острыми углами? Вы имеете в виду, что направление мяча почти параллельно ракетке?   -  person OopsUser    schedule 23.09.2014
comment
Столкновение обнаружено. У меня нет точных цифр, но если это › +- ~40 градусов, то проходит   -  person Jonas Natten    schedule 23.09.2014
comment
Я сделал УДИВИТЕЛЬНУЮ картинку для иллюстрации (зеленые углы работают нормально, красный проходит): oi61.tinypic. ком/15zhw78.jpg   -  person Jonas Natten    schedule 23.09.2014


Ответы (1)


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

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

  1. Вычислите начальный луч из текущего положения мяча, направленный в том же направлении, в котором он движется.
  2. Пересеките это луч с сегментами, которые составляют границы вашего поля.
  3. Вычислите время, необходимое для достижения этой точки пересечения.
  4. Рассчитайте новый луч от точки пересечения к новому вектору движения.
  5. Повторяйте шаги 2-4, пока не достигнете базовой линии игрока. Суммируйте все времена.

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

  1. Проверьте, было ли это время столкновения между предыдущим кадром и текущим. Если бы это было,
  2. Рассчитайте предполагаемое положение весла в этот момент.
  3. Если сегмент весла содержит эту точку пересечения, она была отражена. Рассчитайте новый путь, как описано выше.

Таким образом, вы получите настоящую игровую механику, которая не ограничивается большинством аспектов разработки игр, например, FPS, внезапными лагами и т. д.

person polkovnikov.ph    schedule 23.09.2014
comment
У вас есть пример кода? Судя по звучанию (без знания предмета), это звучит слишком сложно для меня, чтобы реализовать за короткий промежуток времени. Новичок в C++, а «проект» — это всего лишь небольшая школьная задача. - person Jonas Natten; 23.09.2014