Может быть, вы можете попробовать физический подход, учитывающий сохранение импульса и сохранение энергии.
По сути, игрок с массой mp
имеет скорость [vp; 0]
и противник с массой me
, у игрока скорость [ve; 0]
.Нет компонентов, потому что они движутся только горизонтально.Теперь во время столкновения t = t_col
предположим, что центр масс игрока имеет координаты [xp, yp]
, а центр масс врага имеет координаты [xe, ye]
(вы всегда можете настроить их, чтобы убедиться, что эффект отскакивания больше, делая координаты у гораздо более разными, если хотите).
Сохранение импульса говорит нам, что скорости двух объектов, назовите их [Vp, Wp]
и [Ve, We]
сразу после столкновения, вычисляются следующим образом
[Vp; Wp] = [vp; 0] + (1/mp)*[I1; I2];
[Ve; We] = [ve; 0] - (1/me)*[I1; I2];
где, как это обычно бываетПредполагается, что удар является нормальным к поверхности объектов, вектор [I1; I2]
можно принять как выровненный с вектором, соединяющим два центра: [xp - xe; yp - ye]
.Комбинируя эту информацию с сохранением энергии, можно вычислить величину указанного вектора и найти, что
k = (mp*me/(mp+me)) * (vp - ve)*(xp - xe) / ((xp - xe)^2 + (yp - ye)^2);
I1 = k*(xp - xe);
I2 = k*(yp - ye);
Таким образом, в основном, во время столкновения вы получаете в качестве входных данных:
- позиция и скорость игрока:
[xp; yp], [vp; 0]
- позиция и скорость противника:
[xe; ye], [ve; 0]
- масса игрока
mp
и масса противника me
Затем вычислите
k = (mp*me/(mp+me)) * (vp - ve)*(xp - xe) / ((xp - xe)^2 + (yp - ye)^2);
I1 = k*(xp - xe);
I2 = k*(yp - ye);
Vp = vp + (1/mp)*I1;
Wp = (1/mp)*abs(I2);
Ve = ve - (1/me)*I1;
We = (1/me)*abs(I2);
Обратите внимание, что я использовал abs(I2)
, который является абсолютным значением I2
.Это связано с тем, что для одного из двух объектов y-компонента скорости после столкновения будет положительной (поэтому никакой разницы нет), а для другого будет отрицательной.К отрицательному мы также можем добавить тот факт, что объект может отскочить от земли сразу после столкновения (таким образом, столкновение с объектом, а затем столкновение с землей).Таким образом, мы используем закон отражения, подобно тому, как свет отражается зеркалом.
После столкновения в момент времени t = t_col
параболические траектории двух игроков (прежде чем они приземлятся обратно на землю) будут
xp(t) = xp + Vp * (t - t_col);
yp(t) = yp + Wp * (t - t_col) - (g/2) * (t - t_col)^2;
xe(t) = xe + Ve * (t - t_col);
ye(t) = ye + We * (t - t_col) - (g/2) * (t - t_col)^2;
Если вам нужны углы:
cos(angle_p) = Vp / (Vp^2 + Wp^2);
sin(angle_p) = Wp / (Vp^2 + Wp^2);
cos(angle_e) = Ve / (Ve^2 + We^2);
sin(angle_e) = We / (Ve^2 + We^2);
, где angle_p
- угол наклона игрока, а angle_e
- угол врага.