Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Столкновения с пулями в Asteroids

Столкновения с пулями в Asteroids

Поделиться
TexhnolyzeПользовательwww26 мая 201717:33#0
Здравствуйте. Я еще новичок в программировании игр (да и вообще в программировании), сейчас пишу некое подобие Asteroids. Все игровые объекты уже описаны, логика тоже. Но вот со столкновениями беда, а именно столкновения с пулями, т.к. столкновения игрока с астероидами обнаруживаются корректно.
Проблема известная: пули пролетают сквозь астероиды. Я пытался решить задачу 3 - мя способами:
1) Проверить лежит ли пуля внутри астероида (способ совсем не годится, по причине дискретной смены положения)
2) Завести в классе пули дополнительное поле — предыдущее положение, в каждом тике проверять не пересекает ли отрезок (предыдущее положение, текущее положения) какую - нибудь из граней астероида. Этот способ вроде должен работать, но все равно пули пролетают сквозь астероиды. Также этот способ порождает еще одну проблему:
если два астероида расположены близко друг к другу, пуля летит навстречу первому и по всем законам физики должна столкнуться именно с ним, но по какой - то причине первым в системе столкновений будет обработан второй, то пуля столкнется именно с ним (при условии, что отрезок последнего пройденного пути пули пересек второй астероид). 
3) тоже самое, что и второй способ, но мы разбиваем отрезок пули на "(длина вектора скорости / (2 * максимальное расстояние в астероиде до какой - то вершины))". То есть если у нас астероид который можно описать кругом радиуса 5 и длина вектора скорости 20, то мы разбиваем наш отрезок на 20 / (2 * 5) = 2 части и проверяем каждый из как во втором способе.
В общем, люди знающие - объясните, как оно вообще делается, чтобы красиво все было. Также прошу не предлагать движки, ибо сам оч хочу разобраться.

Правка: 26 мая 2017 17:34

TexhnolyzeПользовательwww26 мая 201717:36#1
Забыл сказать, что все описанные способы работают примерно 50 на 50, когда - то лучше, когда вообще ужасно
TailsПостоялецwww26 мая 201718:54#2
Посмотри как эта проблема решается в физ. движках.
TexhnolyzeПользовательwww27 мая 20170:05#3
подскажите плиз, где почитать (желательно на русском) про непрерывное обнаружение столкновений, надо в эту сторону копать как я понял.
mr.DIMASПостоялецwww27 мая 20170:19#4
Можно сделать так: представить пулю и астероид сферами. Обнаружение пересечения сфера-сфера - тривиальное. Чтобы пуля не пролетала сквозь сферу астероида, нужно поделить отрезок (прошлая_позиция - текущая_позиция) на диаметр сферы пульки, получив тем самым количество дополнительных шагов обсчета пересечения. Затем в дополнительном цикле проверить пересечение пуля-астероид с определенным шагом.  Кодом это будет выглядеть как-то так:
vec3 d = bullet->position - bullet->lastPosition; 
vec3 offset = d / bullet->diameter; // шаг разбиения
int steps = Length(d) / bullet->diameter; // количество шагов
for(int i = 0; i < steps; ++i) {
  if(SphereSphereIntersection(bullet->lastPosition + i * offset, bullet->radius, asteroid->position, asteroid->radius)) {
    // пересечение
    break;
  }
}

Этот код подходит для случая, когда скорость пули много больше скорости астероида.

Правка: 27 мая 2017 0:20

TexhnolyzeПользовательwww27 мая 20170:44#5
спасибо конечно, я думал об этом вначале, но это все - таки не то, что нужно.
думаю остановится на следующем пока что:
разбить весь путь пули от прошлой до настоящей позиции на количество частей, равное длине вектора скорости (мы как бы получим слепок всех позиций пули если бы все действительно происходило непрерывно) и просто проверить каждую эту позицию на принадлежность астероиду. В принципе - это то, как я понял идею непрерывного обнаружения столкновений.
}:+()___ [Smile]Постоялецwww27 мая 20171:59#6
Texhnolyze
> 2) Завести в классе пули дополнительное поле — предыдущее положение, в каждом тике проверять не пересекает ли отрезок (предыдущее положение, текущее положения) какую - нибудь из граней астероида.
Именно это и есть CCD, которое ты обозвал "непрерывным обнаружением столкновений".

> Этот способ вроде должен работать, но все равно пули пролетают сквозь астероиды.
Умение отлаживать является неотъемлемой частью программирования, так что советую прокачивать скилл в этом направлении.
До тех пор, пока у тебя "вроде должно работать", но не работает — считай что работа не сделана.

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

> 3) тоже самое, что и второй способ, но мы разбиваем отрезок пули на
Это какая-то лажа для неосиливших нормальное CCD.

/ Форум / Программирование игр / Физика

2001—2017 © GameDev.ru — Разработка игр