Блог ☯

12.04.2017

Создание игры с нуля - Пробивание пуль в игре, гейм мейкер

Создавая игру с нуля где есть стрельба, у вас может возникнуть необходимость сделать пробивание пуль в игре. Сделать так, чтобы пули пробивали врагов.

Однако, вы можете столкнуться с проблемой, делая игру в гейм мейкер студио (game maker studio) или с помощью другой программы.

Так-же рекомендую вам ознакомиться с прошлой статьёй по теме стрельбы:


Кажется что можно просто убрать уничтожение пули при столкновении с врагом и всё. Да, тогда пуля будет пробивать врагов, однако, вот что у вас может получиться.

Посмотрите на эту картинку, которую я набросал:

Создание игры с нуля - Пробивание пуль в игре, гейм мейкер

Примерная модель пробивания пуль в игре

Синий - наш герой. Представим, что мы стреляем в красных врагов, один стоит за другим. Нам нужно чтобы пуля их пробивала. Но что произойдёт, если мы просто уберём уничтожение пули при столкновении с первым врагом? Ведь именно так хочется сделать, если вы думайте о том, как сделать пробивание пуль (стрел, лазерных, плазменных снарядов и т.п.) в игре.

Представим что скорость комнаты равна 30 тиков в секунду (FPS 30). Скорость пули при этом пусть будет 75 (Пуля пролетает 75 пикселей за 1 тик, очень быстро). Враги в этом примере у нас большие, маска коллизии примерно 160 пикселей.

Если у врага допустим 3 жизни, а пуля наносит урон 1, что будет дальше?

Пуля при пролёте через первого врага нанесёт ему урон 2 раза, так-как 2 тика попадают в его область коллизии (столкновения). Первый враг выживет. А вот по второму врагу пуля уже нанесёт 3 урона, и его убьёт.

При этом, заметьте. Скорость пули 75 - это очень быстро. Если у нас скорость пули = 5, то она может нанести одному такому враги при пролёте через него урон 32 раза!

Так пуля убьёт кого угодно. Мы можем зная всё это, делать урон такой пуле не 1, а например 0.05. Тогда урон 32 раза будет примерно 1.6. Вроде нормально. Так раньше делал и я, когда хотел сделать пробивания. Однако, тут всё куда сложнее и с этим методом могут быть проблемы. Разные области коллизии врагов, разные пули и скорости, чётко сложно всё просчитать, если делать таким методом.

Давайте сделаем так, чтобы одна пуля могла нанести урон одному врагу только 1 раз, даже при этом пробив его и полетев дальше.

Для этого используем функцию гейм мейкер студио ds_list

Данная функция очень похожа на одномерные массивы, про них читайте вот тут:


Мы сохраним в пуле (запишем в ней) все id (идентификационные номера) врагов, с которыми она соприкасалась в процессе полёта, а затем будем проверять, чтобы она не била одного врага два раза при пролёте через него.

В создании пули (create) пишем:

HitId = ds_list_create()

Тут мы создаём у каждой пули уникальную локальную переменную (HitId) в которой мы будем хранить данных из вот этого списка - ds_list

Далее, нам нужно две штуки в момент коллизии пули и врага:

if ds_list_find_index(other.HitId,id) == -1  // Проверяем, есть-ли ID врага в списке 
{
 hp-=other.dmg; // Вычитаем ХП в размере урона оружия / пули         ds_list_add(other.HitId,id); // Добавляет ID врага в список 
}

Вот такой код в коллизии. Сначала идёт проверка, а затем мы снимаем жизни и добавляем в список ID еще и этого врага.

Можно кстати уменьшать урон у пули в каждый момент такой колизии, например можно писать: other.dmg *=0.75

Это будет уменьшать урон пули на 25% с каждым столкновениям, она будет как-бы замедляться и слабеть. Скорость кстати тоже можно ей уменьшать при этом, таким-же образом.

В гейм мейкер студио (все версии GM) у каждого объекта есть уникальный ID, вот примерно так его и можно использовать.

Что такое два знака равенства в программировании? Вот такие штуки: "=="

Это означает "equal to", равен чему-то, однако ответом будет не приравнивание (как с одним равно "="), а ответом будет правда или ложь (true / false).

Понятно, что не понятно, объясняю.

x = 5 // Теперь х будет равно цифре 5. Тут всё просто.
x == 5 // Если мы это пишем после первого (х = 5), то нам вернётся - правда (true)

Но от этой правды нам не горячо и не холодно, так что это используется вместе с такими вещами как IF, вместе с проверкой. Так-же правду или ложь мы можем выразить с помощью цифры, 1 - правда, 0 - ложь. По всей видимости ложь (false), так-же можно выразить как -1.

Вот если при столкновении пули и врага этого ID в списке пули еще нет, тогда выполняем всё что дальше: наносим урон, делаем что хотите (может быть рисуем эффект и т.п.), ну и записываем его ID в лист. Вот и всё.

Надеюсь объяснил понятно. Если да - ставьте палец вверх в конце статьи, не забывайте. Создание игры с нуля - штука сложная, а писать статьи про это и делать видео - еще труднее.

Кстати, не забывайте, что в момент коллизии, при пробивании, нам конечно-же не нужно оставлять то, что пуля уничтожается при столкновении с первым врагом, как это обычно делается.

Стоит сказать, что данный метод я подсмотрел на ютуб канале SlasherXGAMES, в видео - GameMaker Tutorial - Bullet Penetration. У него много полезных уроков, однако они на английском. Я иногда что-то подсматриваю на Английском, если материалов на Русском не хватает и перевожу для вас. Но большую часть уроков я делаю от себя.

Ну и как-же без видео на моём ютуб канале по этой теме? Если не поняли тут, можете глянуть этот ролик про пробивание пуль в игре, всего 6 минут и есть наглядная демонстрация.