Подтвердить что ты не робот

Как рассчитать угол отскока?

Я играл с ним некоторое время, но я просто не могу понять.

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

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

Является ли решение, которое я ищу достаточно продвинутым?

Есть ли относительно простой способ сделать это?

4b9b3361

Ответ 1

Я думаю, что более простой способ сделать это - использовать скорость ракеты вместо вычисления углов. Скажем, у вас есть ракета с xVelocity и yVelocity для представления ее движения по горизонтали и по вертикали. Эти скорости могут быть положительными или отрицательными, чтобы представлять левый, правый, вверх или вниз.

  • Если ракета попадает на верхнюю или нижнюю границу, обратный знак yVelocity.
  • Если ракета попадает на левую или правую границу, обратный знак xVelocity.

Это будет поддерживать движение на противоположной оси.

Заимствование изображения из ответа ChrisF, скажем, что ракета начинается в позиции I.

Angle of Reflection

Если значения xVelocity и yVelocity оба являются положительными (в 2D-графике справа и внизу, как правило, положительные) ракета будет двигаться в указанном направлении. Пусть просто присвойте значения

xVelocity = 3
yVelocity = 4

Когда ракета попадает в стену в положении C, ее xVelocity не следует изменять, но ее yVelocity следует поменять на -4, чтобы он возвращался в направлении вверх, но продолжает идти вправо.

Преимущество этого метода в том, что вам нужно только отслеживать ракеты xPosition, yPosition, xVelocity и yVelocity. Используя только эти четыре компонента и скорость обновления вашей игры, ракета всегда будет перерисовываться в правильном положении. Когда вы займетесь более сложными препятствиями, которые не имеют прямых углов или движутся, будет намного легче работать со скоростями X и Y, чем с углами.

Ответ 2

Вы можете подумать, что, поскольку ваши стены выровнены с координатными осями, имеет смысл написать специальный код корпуса (для вертикальной стены отрицайте координату x для скорости, для горизонтальной стены отрицайте y-координату скорости). Однако, как только вы играете хорошо с вертикальными и горизонтальными стенами, возможно, следующая вещь, о которой вы подумаете: "А как насчет стен под произвольными углами?" Поэтому стоит подумать об общем случае с самого начала.

В общем случае предположим, что ваша ракета имеет скорость v и попадает на стену с нормальной поверхностью n.

Missile with vector v about to obliquely hit a wall with surface normal n.

Разделить v на компоненты u, перпендикулярные к стене, и w.

Right-angled triangle with hypotenuse for v, short side u parallel to wall and long side w parallel to wall.

Где:

u= (v - n/ n - n) n
w= v - u

Здесь v - n - dot product векторов v и n. См. Ссылку для объяснения того, как ее вычислить. Точечный продукт n - n оценивает квадрат длины нормального вектора; если вы всегда сохраняете свои нормали в виде единичных векторов, то n n= 1, и вы можете опустить деление.

После подпрыгивания компонент движения, параллельный стене, зависит от трения f, а компонент, перпендикулярный к стенке, зависит от эластичности, которая может быть задана в виде коэффициент реституции r.

Итак, скорость после столкновения v '= f w - r u. В идеальном упругом, без трения столкновении, v '= w - u; т.е. движение отражается относительно нормали в точке столкновения, как на диаграмме, приведенной в ответе Билла.

Этот подход работает одинаково в трех измерениях.

(Очевидно, это очень упрощенное понятие подпрыгивания, оно не учитывает импульс или деформацию angular. Но для многих видов видеоигр подобное упрощение вполне адекватно.)

Ответ 3

Для идеальных частиц (& light) угол отражения равен углу падения, как показано на этой диаграмме (из commons.wikimedia.org).

Angle of Reflection

Сделайте поиск "угла отражения" (без кавычек) в Google.

Это немного сложнее, если учесть эластичность и материалы объекта и препятствия;)

Ответ 4

В качестве ответа на конкретный физический вопрос, который вы задаете, я бы рекомендовал Венди Сталер книгу "Начальная математика и физика для программистов игры". Я нашел это весьма полезным для моих игр/проектов программирования физики.

Код, который прилагается к книге, это С++, но если вы знаете С#, было бы довольно легко сделать преобразование.

Имейте хороший!

Ответ 5

У меня была эта проблема, единственный способ, которым я нашел, - это разделение осей столкновения!

Попробуйте:

x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);

if (x < 0 || x > canvas.width) {
     angle = 180 - angle;   
}
else if (y < 0 ||y > canvas.height) {
     angle = 360 - angle; 
}

Надеюсь, это поможет вам!

Ответ 6

Не сложно вообще - псевдокод:

angleObjectHitWall = a;
bounceAngle = 180-a;

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

Ответ 7

180-a не будет работать во всех случаях, если только вы просто не работаете с откатом на верхней поверхности, когда X увеличивается.

Одно направление для головы - форумы XNA или выбор кода образца XNA. Это С#, и он предназначен для создания игр. Я не утверждаю, что вы хотите создавать свои игры в XNA, но это отличный инструмент, и он бесплатный.

Ответ 8

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

Я предлагаю прочитать эту запись в wikipedia, чтобы получить общее представление о глубине вашего вопроса.

Если вы хотите сделать это "выглядящим правдоподобным", я не буду слишком беспокоиться об этом и использовать ответ Билла Ящера, однако, если вы хотите сделать это правильно, у вас будет довольно приключение. Не позволяйте этому пугать вас! Удачи!

Ответ 9

if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}

Он работает и прост, удачи.