Алгоритм столкновения для 2 движущихся объектов - PullRequest
0 голосов
/ 30 октября 2010

это математическая задача для 2d игры.

Given 2 object ( 2 car, 2 tank, 2...), for each object i know: 
1. X, Y 
2. Actual Speed
3. Degree of movement (or radiant)

Как рассчитать "эффект" столкновения для 2 объекта

Ps:

Я «перемещаю» объект с помощью этой простой формулы каждый тик моего «игрового цикла»:

ychange = Math.Sin(radiant) * ((carspeed / xVar));
xchange = Math.Cos(radiant) * ((carspeed / xVar));

(где xVar - это «мультипликатор», чтобы замедлить мою машину на экране)

И для «первого» объекта, который сталкивается, если я добавлю «минус» (-) перед этой формулой, я могу имитировать хороший «отскок» первого объекта ... но не для второго. 1013 *

Так что мой вопрос касается способа вычисления хорошего (не идеального!) И более реалистичного «эффекта удара» для второго объекта.

Спасибо за вашу помощь

Ответы [ 4 ]

3 голосов
/ 30 октября 2010

Несколько месяцев назад я реализовал игру в снукер. Я использовал следующий код, чтобы два шара столкнулись. Обратите внимание, что они не являются ограничивающими рамками.

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

Это сработало как шарм в моей игре.

 float   dx = b1->x - b2->x, dy = b1->y - b2->y;
    float   d = sqrt(sqr(dx) + sqr(dy));
    float   vp1, vp2, vx1, vx2, vy1, vy2;
    vx1 = ballSpeedX(b1);
    vx2 = ballSpeedX(b2);
    vy1 = ballSpeedY(b1);
    vy2 = ballSpeedY(b2);
    vp1 = vx1 * dx / d + vy1 * dy / d;
    vp2 = vx2 * dx / d + vy2 * dy / d;

    float   distance = sqrt(sqr(dx) + sqr(dy));

//  Unit vector in the direction of the collision.
    float   ax = dx / distance, ay = dy / distance;

//  Projection of the velocities in these axes.
    float   va1 = vx1 * ax + vy1 * ay, vb1 = -vx1 * ay + vy1 * ax;
    float   va2 = vx2 * ax + vy2 * ay, vb2 = -vx2 * ay + vy2 * ax;

//  New velocities in these axes (after collision): edmass / b2->mass);
    float   vaP2 = va2 + (1.0 + D_BALL_ELASTIC_COEFFICIENT) * (va1 - va2) / (1.0 + b2->mass / b1->mass);

//  Undo the projections.
    vx1 = vaP1 * ax - vb1 * ay; vy1 = vaP1 * ay + vb1 * ax; // new vx,vy for ball 1 after collision.
    vx2 = vaP2 * ax - vb2 * ay; vy2 = vaP2 * ay + vb2 * ax; // new vx,vy for ball 2 after collision.

    b1->speed = sqrt(sqr(vx1) + sqr(vy1));
    b1->angle = acos(fabs(vx1 / b1->speed));

    b2->speed = sqrt(sqr(vx2) + sqr(vy2));
    b2->angle = acos(fabs(vx2 / b2->speed));

Этот код был написан на чистом C. То, как я храню данные о движении, точно такое же, как у вас. Переменные b1 и b2 являются шарами.

Я считаю, что сам код не сложен для понимания, но физика не тривиальна.

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

2 голосов
/ 30 октября 2010

Самый простой способ - иметь их скорости свопа . Это имеет смысл, если они идентичны.

Если вы хотите сделать больше, вы можете выбрать случайное значение для параметра, который будет определять, есть ли у них скользящее столкновение (едва касающееся) или полное воздействие, или что-то среднее. Вы также можете имитировать разные массы двух объектов (когда мотоцикл врезается в грузовой автомобиль, с ним мало что происходит). Наконец, вы можете столкнуться лишь частично эластично; то есть они не подпрыгивают как резиновые шарики, они хрустят и теряют часть энергии. Это потребует математики и понимания физики.

1 голос
/ 30 октября 2010

Вот объяснение физики:

У вас есть четыре неизвестных: скорости x и y каждого шара после столкновения.

Итак, вам нужно четыре уравнения.

Сохранение импульса в х и у дает два.Mom = mv
Сохранение кинетической энергии дает треть;Ke = 1/2 * mv ^ 2 (до и после)

Кроме того, принцип относительности может быть использован для предположения, что один шар изначально неподвижен, скажем, uB.x = uB.y = 0

И импульс должен происходить вдоль линии, которая соединяется между центрами каждого шара, во время удара.Таким образом, если вы предположили, что шар B изначально находился в состоянии покоя, теперь он будет двигаться в направлении этой линии, поэтому вы можете выразить vB.y = f + g * vB.x, сократив число неизвестных до 3.

Три неизвестных, три уравнения.Ура!

Если столкновение не является упругим, то это зависит от того, насколько точно вы хотите смоделировать.Что-то вроде Ke_after = 0,99 * Ke_before, а затем добавьте это в математику.

Я оставляю читателю в качестве упражнения вывод полных уравнений.

0 голосов
/ 30 октября 2010

Хммм ... прошло много времени с тех пор, как я сталкивался с разработкой игр, поэтому прислушайтесь к моему совету.Вы пытались «перевернуть» степень движения или просто добавить один пи к radiant?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...