teams: megainformatic, телеграм: megainformatic, онлайн-чат (megainformatic live chat), форма обратной связи
Онлайн Школа Компьютерных Наук Андрея Синицина

Добро пожаловать в нашу школу ! Давайте вместе откроем путь к новым перспективам !!!
Fle game engine - реализация коллизий на примере проекта Многоликий: dress
О реализации столкновений на движке fle game engine я уже рассказывал в статье Проверка столкновений В упомянутой статье предполагалось, что у вас перед глазами открыт исходный код проекта и Вы можете его посмотреть. Сейчас мы рассмотрим более общий пример реализации коллизий. И в качестве примера будет рассказано о том, как реализуются коллизии в игре Многоликий: dress.В чем суть задачи: по экрану слева-направо движутся враги и вам нужно фиксировать столкновение между ними и персонажем. В данном случае этот персонаж - девушка по имени Ри. Если столкновение зафиксировано, то в ответ надо предпринимать какие-либо действия, например снижать полоску индикатора на некоторое значение, так называемый урон fDamage наносимый данным врагом. Чтобы лучше понимать суть - посмотрите как выглядит игровой процесс (на видео еще не показано как работают столкновения, показано лишь перемещение врагов и персонажа). На первый взгляд может показаться, что работа с коллизиями (столкновениями), особенно для новичков, представляет что-то непонятное и даже сложное. Например во многих движках для настройки коллизий не нужно выполнять какой-то сложный набор действий, однако детали того, как работают коллизии могут быть скрыты от вас. И уж если вдруг вам потребуется изменить поведение коллизий самым нетривиальным образом, то с большой вероятностью в движках, где вы никак не можете повлиять на код реализации коллизий и их использование нестандатно, Вам придется искать какой-то другой путь. В движке fle game engine, который написан на c++ directx 9 и имеет полный открытый исходный код все это не представляет сложности. За тем лишь исключением, что использование коллизий в вашем проекте поначалу может показаться более громоздким, нежели в других движках. Но этот недостаток с лихвой покрывается тем, что Вы можете не только применять коллизии каким-то нестандартным образом, но можете и изменить сам исходный код - добавив какие-то новые возможности. Тем самым нетривиальное использование не имеет никаких ограничений, а в настоящих игровых проектах, где чаще всего и нужно как можно больше чего-то нестандартного, все это найдет применение. Итак, Реализация столкновений включает следующие шаги: 1) Определить размеры collision box - прямоугольной области у игрового объекта, при попадании в которую будет фиксироваться столкновение; 2) Подключить необходимые для работы с коллизиями модули в коде; 3) Добавить код осуществляющий загрузку параметров коллизий у игровых объектов и освобождение загруженных ресурсов при завершении работы игры; 4) В нужном месте кода вызывать метод осуществляющий проверку столкновения между персонажем и врагами; 5) В соответствии с фиксацией столкновения выпонять какие-либо игровые действия, например изменять полоску индикатора и если она достигла определенных значений, например 0 - вызывать экран Game over. Также выполнять какие-то еще необходимые действия. Рассмотрим каждый из шагов более подробно. 1) Определить размеры collision box - прямоугольной области у игрового объекта, при попадании в которую будет фиксироваться столкновение; для этого в папке ресурсов проекта - в моем случае это папка Media4 для удобства я создал внутри отдельную папку Media4\prop_desc так что внутри неё создаем 2 файла с таким содержимым Media4\prop_desc\collision_rects_desc6.txt hero_walk; 0.0525f; -0.1800f; 0.2025f; -0.3800f; 0.785f; enemy_walk; 0.035f; -0.0733f; 0.2075f; -0.15f; 0.6f; hero_walk - задаем 4 значения для левого верхнего - left, top, правого нижнего углов right, bottom collision box у персонажа, а последний параметр означает масштаб нашего collision box. 0.785f означает, что он сжат. Если было бы 1.0f - имеет тот же масштаб, что и спрайт. А если будет > 1.0f - значит растянут относительно спрайта (такое тоже может быть для каких-либо целей). Но обычно масштаб < 1.0f поскольку чаще всего мы не хотим чтобы вся область спрайта являлась одновременно и областью для фиксации столкновений. Обычно эту область делают значительно меньше - т. к. чтобы столкновение произошло объекты должны визуально коснуться друг друга - чего нельзя будет достичь при масштабе 1.0f т. к. вокруг спрайта будет обязательно пустое пространство и поэтому столкновение будет фиксироваться еще задолго до того, как объекты соприкоснутся - и это может вызвать недоумение игрока, хотя все зависит от особенностей конкретного проекта. Это может использоваться и намеренно. аналогично задаем для врага - enemy_walk параметры имеют отрицательное значение по y означая, что от верхней границы объекта нужно отступить вниз указанное количество единиц размера (не пикселей ! т. к. используются относительные значения не зависящие от разрешения экрана) Media4\prop_desc\game_object_class_properies6.txt // // описание свойств героя // begin =; Name = hero_walk; Collided = true; end =; // // описание свойств врага // begin =; Name = enemy_walk; Collided = true; end =; Здесь все еще проще. Просто задаем возможность наличия коллизии. Могут быть случаи когда проверку столкновения делать нужно, но фиксировать коллизию - нет. Поэтому значение Collided = true можно у объекта задать и как Collided = false Чего не позволят сделать вам движки, где функционал коллизий применяется "из коробки", то есть Вы не знаете внутренние подробности их устройства. Обратите внимание, что оба файла имеют номерной индекс 6 Media4\prop_desc\collision_rects_desc6.txt Media4\prop_desc\game_object_class_properies6.txt это означает, что данная коллизия в моем проекте уже 6 по счету. А индексы даются чтобы отделить код и логику от коллизий которые уже используются в проекте, но для других целей. То есть в моем проекте получается используется 6 разных коллизий, и коллизия с врагами и персонажем - уже 6 по счету. 2) Подключить необходимые для работы с коллизиями модули в коде; Происходит это так - нужно взять 4 файла для работы с кодом коллизий - в моем проекте эти файлы находятся в папке start\game_common\ за основу я беру файлы других коллизий, которые у меня уже были в проекте например файлы collision5.h collision5.cpp game_object_properties5.h game_object_properties5.cpp я делаю копию этих 4 файлов и переименовываю в collision6.h collision6.cpp game_object_properties6.h game_object_properties6.cpp чтобы не было конфликта имен переменных используемых внутри других файлов коллизий я все именования имеющие индекс 5 в коде заменяю на 6 пример collision6.h typedef struct GAMEOBJECTCOLLISIONRECT5 { CString* Name; //game object name D3DXVECTOR2 LeftTop; D3DXVECTOR2 RightBottom; float BaseScale; } GameObjectCollisionRect5, *LPGAMEOBJECTCOLLISIONRECT5; нужно превратить в typedef struct GAMEOBJECTCOLLISIONRECT6 { CString* Name; //game object name D3DXVECTOR2 LeftTop; D3DXVECTOR2 RightBottom; float BaseScale; } GameObjectCollisionRect6, *LPGAMEOBJECTCOLLISIONRECT6; и все остальные элементы в коде во всех этих 4 файлах. Далее нужно подключить эти 4 файла в ваш проект. Сначала добавив их в окне Solution explorer, а затем и указав в коде ссылки на их подключение. В своем проекте я подключаю их в файле gdess.cpp такими строками кода в самом начале файла - #include "game_object_properties6.h" #include "collision6.h" Собственно говоря с этого момента использование коллизий в проекте подключено. Остается добавить код, который будет работать с вашими коллизиями - загрузит и освободит (когда нужно) файлы с параметрами коллизий, выполнит проверку факта столкновения (коллизии) между игровыми объектами и наконец код который в зависимости от коллизий будет выполнять какие-то действия в игре - изменение количества очков, энергии и что угодно еще - все что задумано в игре. Таким образом следующий шаг - 3) Добавить код осуществляющий загрузку параметров коллизий у игровых объектов и освобождение загруженных ресурсов при завершении работы игры; Для этого в своем проекте в модуле gdess.cpp я добавил такой код - в методе void CGdess::Load() { делаю вызов //загрузка свойств объектов необходимых для проверки столкновений LoadGameObjProperties6(GameObjectClassProperties6); а в методе void CGdess::Before_Free() { FreeGameObjProperties6(); //освобождаем ресурсы выделенные для объектов проверки //столкновений Если эти 2 важных элемента забыть - то код работы с коллизиями будет давать ошибку !!! Если все хорошо и параметры загружены (и будут освобождены когда нужно), можно двигаться дальше - 4) В нужном месте кода вызывать метод осуществляющий проверку столкновения между персонажем и врагами; для этого в модуле gdess.cpp я написал такой метод void CGdess::RiContactEnemy() { m_bRiContactWithEnemyDetected = false; //это будет у нас флаг фиксации момента столкновения //между персонажем и врагом LPGAMEOBJECTPROPERTIES6 heroProp = GetGameObjInstProperty6(hero_prop6); //получаем свойства объекта //столкновений у персонажа игрока LPGAMEOBJECTPROPERTIES6 enemyProp = GetGameObjInstProperty6(enemy_prop6); //и врага //проходим по циклу из всех врагов, которые есть в сцене for ( int iEnemy = 0; iEnemy < m_i_enemy_creatures_num; iEnemy++ ) { //если с данным врагом столкновение еще не зафиксировано - if ( m_arr_EnemyCreatures[iEnemy].isCollided ) { //делаем вызов функции проверки столкновения m_arr_EnemyCreatures[iEnemy].bContactDetected = CollisionDetected6( heroProp->CollisionRectIndex, //индекс области столкновения (collision box) у игрока enemyProp->CollisionRectIndex, //тоже у врага &D3DXVECTOR2( m_v2_Scene_Pos.x, //координаты игрока на экране m_v2_Scene_Pos.y + 0.25f), //в координаты может вноситься поправка чтобы достичь //определенного эффекта - столкновения фиксировались бы вплотную или на некотором //расстоянии &D3DXVECTOR2( m_arr_EnemyCreatures[iEnemy].Pos.x - 0.05f, //координаты врага m_arr_EnemyCreatures[iEnemy].Pos.y), 1.0f, //масштаб игрока и врага 1.0f); if ( m_arr_EnemyCreatures[iEnemy].bContactDetected ) //если коллизия с врагом зафиксирована Damage_To_Player_By_Enemy_Creature(iEnemy); //вызываем метод который выполняет нанесение //урона игроку - в моем примере снижается индикатор прогресса в левом верхнем углу экрана //метод нужен отдельный т. к. в моем примере разные враги могут наносить немного разный //урон //ну и наконец, если как минимум одно или более столкновений зафиксировано //выставляем флаг столкновений в true m_bRiContactWithEnemyDetected |= m_arr_EnemyCreatures[iEnemy].bContactDetected; //еще может быть вариант когда нужно подсчитывать количество произошедших столкновений //но в данном примере я это не использую } } g_i_Test_Var_3 = (int)m_bRiContactWithEnemyDetected; //это вывод значения в отладочную переменную //на экран - чтобы убедиться - фиксация столкновений работает (1 - признак что столкновение было, 0 - нет) //собственно здесь можно (при желании) как раз поставить счетчик столкновений т. е. такой - if ( m_bRiContactWithEnemyDetected ) { m_b_Collisions_6_Count++; //предварительно объявив переменную в модуле gdess.h } //но здесь это показано лишь для демонстрации. В проекте dress я это не использовал. } Сам метод RiContactEnemy() в моем случае вызывается тут - void CGdess::Move_Enemy_Creatures() { //... RiContactEnemy(); то есть в методе осуществляющем перемещения врагов по экрану. Враги переместились на шаг - и далее проверяется не столкнулся ли игрок с одним из врагов. Вот так это и работает. И наконец финальный штрих 5) В соответствии с фиксацией столкновения выпонять какие-либо игровые действия, например изменять полоску индикатора и если она достигла определенных значений, например 0 - вызывать экран Game over. Также выполнять какие-то еще необходимые действия. Просто покажу код метода Damage_To_Player_By_Enemy_Creature, который уже упоминался выше. void CGdess::Damage_To_Player_By_Enemy_Creature(int iEnemy) { //если индекс врага больше чем доступный - ничего не делаем if ( iEnemy < 0 || iEnemy > (m_i_enemy_creatures_num-1) ) return; //если враг не является видимым - ничего не делаем if ( !m_arr_EnemyCreatures[iEnemy].Visible ) return; //снижаем полоску индикатора на значение урона наносимого данным врагом m_f_Aim_Indicator_Percent = m_f_Aim_Indicator_Percent - m_arr_EnemyCreatures[iEnemy].fDamage * g_fElapsedTime * 0.15f; } Вот собственно и все. Как видите реализация столкновений не такое уж сложное действие, как может показаться на первый взгляд.
оцените статью:
0

0

megainformatic 2006 - 2025 карта сайта
В чем суть задачи: по экрану слева-направо движутся враги и вам нужно
фиксировать столкновение между ними и персонажем. В данном случае
этот персонаж - девушка по имени Ри.
Если столкновение зафиксировано, то в ответ надо предпринимать какие-либо действия,
например снижать полоску индикатора на некоторое значение, так называемый урон
fDamage
наносимый данным врагом.
Чтобы лучше понимать суть - посмотрите как выглядит игровой процесс
(на видео еще не показано как работают столкновения, показано лишь
перемещение врагов и персонажа).
На первый взгляд может показаться, что работа с коллизиями (столкновениями),
особенно для новичков, представляет что-то непонятное и даже сложное.
Например во многих движках для настройки коллизий не нужно выполнять
какой-то сложный набор действий, однако детали того, как работают
коллизии могут быть скрыты от вас.
И уж если вдруг вам потребуется изменить поведение коллизий самым нетривиальным
образом, то с большой вероятностью в движках, где вы никак не можете повлиять
на код реализации коллизий и их использование нестандатно, Вам придется искать
какой-то другой путь.
В движке fle game engine, который написан на c++ directx 9 и имеет полный открытый
исходный код все это не представляет сложности.
За тем лишь исключением, что использование коллизий в вашем проекте поначалу может
показаться более громоздким, нежели в других движках.
Но этот недостаток с лихвой покрывается тем, что Вы можете не только применять коллизии
каким-то нестандартным образом, но можете и изменить сам исходный код - добавив
какие-то новые возможности.
Тем самым нетривиальное использование не имеет никаких ограничений, а в настоящих
игровых проектах, где чаще всего и нужно как можно больше чего-то нестандартного,
все это найдет применение.
Итак,
Реализация столкновений включает следующие шаги:
1) Определить размеры collision box - прямоугольной области у игрового объекта,
при попадании в которую будет фиксироваться столкновение;
2) Подключить необходимые для работы с коллизиями модули в коде;
3) Добавить код осуществляющий загрузку параметров коллизий у игровых объектов
и освобождение загруженных ресурсов при завершении работы игры;
4) В нужном месте кода вызывать метод осуществляющий проверку столкновения
между персонажем и врагами;
5) В соответствии с фиксацией столкновения выпонять какие-либо игровые действия,
например изменять полоску индикатора и если она достигла определенных значений,
например 0 - вызывать экран Game over. Также выполнять какие-то еще необходимые
действия.
Рассмотрим каждый из шагов более подробно.
1) Определить размеры collision box - прямоугольной области у игрового объекта,
при попадании в которую будет фиксироваться столкновение;
для этого в папке ресурсов проекта -
в моем случае это папка
Media4
для удобства я создал внутри отдельную папку
Media4\prop_desc
так что внутри неё создаем 2 файла с таким содержимым
Media4\prop_desc\collision_rects_desc6.txt
hero_walk; 0.0525f; -0.1800f; 0.2025f; -0.3800f; 0.785f;
enemy_walk; 0.035f; -0.0733f; 0.2075f; -0.15f; 0.6f;
hero_walk - задаем 4 значения для левого верхнего - left, top, правого нижнего углов right, bottom
collision box у персонажа, а последний параметр означает масштаб нашего collision box.
0.785f означает, что он сжат. Если было бы 1.0f - имеет тот же масштаб, что и спрайт.
А если будет > 1.0f - значит растянут относительно спрайта (такое тоже может быть
для каких-либо целей).
Но обычно масштаб < 1.0f поскольку чаще всего мы не хотим чтобы вся область спрайта
являлась одновременно и областью для фиксации столкновений.
Обычно эту область делают значительно меньше - т. к. чтобы столкновение произошло объекты
должны визуально коснуться друг друга - чего нельзя будет достичь при масштабе 1.0f т. к.
вокруг спрайта будет обязательно пустое пространство и поэтому столкновение будет фиксироваться
еще задолго до того, как объекты соприкоснутся - и это может вызвать недоумение игрока,
хотя все зависит от особенностей конкретного проекта. Это может использоваться и
намеренно.
аналогично задаем для врага -
enemy_walk
параметры имеют отрицательное значение по y означая,
что от верхней границы объекта нужно отступить вниз указанное
количество единиц размера (не пикселей ! т. к. используются относительные
значения не зависящие от разрешения экрана)
Media4\prop_desc\game_object_class_properies6.txt
//
// описание свойств героя
//
begin =;
Name = hero_walk;
Collided = true;
end =;
//
// описание свойств врага
//
begin =;
Name = enemy_walk;
Collided = true;
end =;
Здесь все еще проще.
Просто задаем возможность наличия коллизии.
Могут быть случаи когда проверку столкновения делать нужно,
но фиксировать коллизию - нет.
Поэтому значение
Collided = true
можно у объекта задать и как
Collided = false
Чего не позволят сделать вам движки, где функционал коллизий применяется
"из коробки", то есть Вы не знаете внутренние подробности их устройства.
Обратите внимание, что оба файла имеют номерной индекс 6
Media4\prop_desc\collision_rects_desc6.txt
Media4\prop_desc\game_object_class_properies6.txt
это означает, что данная коллизия в моем проекте уже 6 по счету.
А индексы даются чтобы отделить код и логику от коллизий которые уже
используются в проекте, но для других целей.
То есть в моем проекте получается используется 6 разных коллизий,
и коллизия с врагами и персонажем - уже 6 по счету.
2) Подключить необходимые для работы с коллизиями модули в коде;
Происходит это так -
нужно взять 4 файла для работы с кодом коллизий -
в моем проекте эти файлы находятся в папке
start\game_common\
за основу я беру файлы других коллизий, которые у меня
уже были в проекте например файлы
collision5.h
collision5.cpp
game_object_properties5.h
game_object_properties5.cpp
я делаю копию этих 4 файлов и переименовываю в
collision6.h
collision6.cpp
game_object_properties6.h
game_object_properties6.cpp
чтобы не было конфликта имен переменных используемых
внутри других файлов коллизий я все именования имеющие
индекс 5 в коде заменяю на 6
пример
collision6.h
typedef struct GAMEOBJECTCOLLISIONRECT5
{
CString* Name; //game object name
D3DXVECTOR2 LeftTop;
D3DXVECTOR2 RightBottom;
float BaseScale;
} GameObjectCollisionRect5, *LPGAMEOBJECTCOLLISIONRECT5;
нужно превратить в
typedef struct GAMEOBJECTCOLLISIONRECT6
{
CString* Name; //game object name
D3DXVECTOR2 LeftTop;
D3DXVECTOR2 RightBottom;
float BaseScale;
} GameObjectCollisionRect6, *LPGAMEOBJECTCOLLISIONRECT6;
и все остальные элементы в коде во всех этих 4 файлах.
Далее нужно подключить эти 4 файла в ваш проект.
Сначала добавив их в окне Solution explorer,
а затем и указав в коде ссылки на их подключение.
В своем проекте я подключаю их
в файле
gdess.cpp
такими строками кода в самом начале файла -
#include "game_object_properties6.h"
#include "collision6.h"
Собственно говоря с этого момента использование коллизий в проекте подключено.
Остается добавить код, который будет работать с вашими коллизиями -
загрузит и освободит (когда нужно) файлы с параметрами коллизий,
выполнит проверку факта столкновения (коллизии) между игровыми объектами
и наконец
код который в зависимости от коллизий будет выполнять какие-то действия
в игре - изменение количества очков, энергии и что угодно еще - все что
задумано в игре.
Таким образом следующий шаг -
3) Добавить код осуществляющий загрузку параметров коллизий у игровых объектов
и освобождение загруженных ресурсов при завершении работы игры;
Для этого в своем проекте в модуле
gdess.cpp
я добавил такой код -
в методе
void CGdess::Load()
{
делаю вызов
//загрузка свойств объектов необходимых для проверки столкновений
LoadGameObjProperties6(GameObjectClassProperties6);
а в методе
void CGdess::Before_Free()
{
FreeGameObjProperties6(); //освобождаем ресурсы выделенные для объектов проверки
//столкновений
Если эти 2 важных элемента забыть - то код работы с коллизиями будет давать
ошибку !!!
Если все хорошо и параметры загружены (и будут освобождены когда нужно),
можно двигаться дальше -
4) В нужном месте кода вызывать метод осуществляющий проверку столкновения
между персонажем и врагами;
для этого в модуле
gdess.cpp
я написал такой метод
void CGdess::RiContactEnemy()
{
m_bRiContactWithEnemyDetected = false; //это будет у нас флаг фиксации момента столкновения
//между персонажем и врагом
LPGAMEOBJECTPROPERTIES6 heroProp = GetGameObjInstProperty6(hero_prop6); //получаем свойства объекта
//столкновений у персонажа игрока
LPGAMEOBJECTPROPERTIES6 enemyProp = GetGameObjInstProperty6(enemy_prop6); //и врага
//проходим по циклу из всех врагов, которые есть в сцене
for ( int iEnemy = 0; iEnemy < m_i_enemy_creatures_num; iEnemy++ )
{
//если с данным врагом столкновение еще не зафиксировано -
if ( m_arr_EnemyCreatures[iEnemy].isCollided )
{
//делаем вызов функции проверки столкновения
m_arr_EnemyCreatures[iEnemy].bContactDetected = CollisionDetected6(
heroProp->CollisionRectIndex, //индекс области столкновения (collision box) у игрока
enemyProp->CollisionRectIndex, //тоже у врага
&D3DXVECTOR2(
m_v2_Scene_Pos.x, //координаты игрока на экране
m_v2_Scene_Pos.y + 0.25f), //в координаты может вноситься поправка чтобы достичь
//определенного эффекта - столкновения фиксировались бы вплотную или на некотором
//расстоянии
&D3DXVECTOR2(
m_arr_EnemyCreatures[iEnemy].Pos.x - 0.05f, //координаты врага
m_arr_EnemyCreatures[iEnemy].Pos.y),
1.0f, //масштаб игрока и врага
1.0f);
if ( m_arr_EnemyCreatures[iEnemy].bContactDetected ) //если коллизия с врагом зафиксирована
Damage_To_Player_By_Enemy_Creature(iEnemy); //вызываем метод который выполняет нанесение
//урона игроку - в моем примере снижается индикатор прогресса в левом верхнем углу экрана
//метод нужен отдельный т. к. в моем примере разные враги могут наносить немного разный
//урон
//ну и наконец, если как минимум одно или более столкновений зафиксировано
//выставляем флаг столкновений в true
m_bRiContactWithEnemyDetected |= m_arr_EnemyCreatures[iEnemy].bContactDetected;
//еще может быть вариант когда нужно подсчитывать количество произошедших столкновений
//но в данном примере я это не использую
}
}
g_i_Test_Var_3 = (int)m_bRiContactWithEnemyDetected; //это вывод значения в отладочную переменную
//на экран - чтобы убедиться - фиксация столкновений работает (1 - признак что столкновение было, 0 - нет)
//собственно здесь можно (при желании) как раз поставить счетчик столкновений т. е. такой -
if ( m_bRiContactWithEnemyDetected )
{
m_b_Collisions_6_Count++; //предварительно объявив переменную в модуле gdess.h
}
//но здесь это показано лишь для демонстрации. В проекте dress я это не использовал.
}
Сам метод
RiContactEnemy()
в моем случае вызывается тут -
void CGdess::Move_Enemy_Creatures()
{
//...
RiContactEnemy();
то есть в методе осуществляющем перемещения врагов по экрану.
Враги переместились на шаг - и далее проверяется не столкнулся
ли игрок с одним из врагов.
Вот так это и работает.
И наконец финальный штрих
5) В соответствии с фиксацией столкновения выпонять какие-либо игровые действия,
например изменять полоску индикатора и если она достигла определенных значений,
например 0 - вызывать экран Game over. Также выполнять какие-то еще необходимые
действия.
Просто покажу код метода Damage_To_Player_By_Enemy_Creature, который уже упоминался
выше.
void CGdess::Damage_To_Player_By_Enemy_Creature(int iEnemy)
{
//если индекс врага больше чем доступный - ничего не делаем
if ( iEnemy < 0 || iEnemy > (m_i_enemy_creatures_num-1) )
return;
//если враг не является видимым - ничего не делаем
if ( !m_arr_EnemyCreatures[iEnemy].Visible )
return;
//снижаем полоску индикатора на значение урона наносимого данным врагом
m_f_Aim_Indicator_Percent = m_f_Aim_Indicator_Percent -
m_arr_EnemyCreatures[iEnemy].fDamage * g_fElapsedTime * 0.15f;
}
Вот собственно и все.
Как видите реализация столкновений не такое уж сложное действие, как
может показаться на первый взгляд.