Как рассчитать угол отскока?
Я играл с ним некоторое время, но я просто не могу понять.
Я сделал танк, который стреляет ракетами, и когда ракеты врезаются в стены, я хочу, чтобы они отскакивали, но я хочу, чтобы они отскакивали под прямым углом.
Прямо сейчас у меня нет никаких препятствий, ракеты просто отскакивают, когда они выходят за пределы viewportRectangle
, которые я сделал.
Является ли решение, которое я ищу достаточно продвинутым?
Есть ли относительно простой способ сделать это?
Ответы
Ответ 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;
}
Он работает и прост, удачи.