*Вы можете найти ссылки на предыдущие части в нижней части этого руководства.

Ранее мы остановились на том месте, где создали первые два уровня нашей игры. В этой части мы создадим нашу бомбу, которая будет визуально перемещаться по нашей сцене, когда ее создаст генератор бомб. Мы создадим генератор бомб в следующей части. Вы можете думать о бомбе как о бочке в Donkey Kong, а о создателе бомбы как о разъяренной горилле!

ЧТО ВЫ УЗНАЕТЕ В ЭТОЙ ЧАСТИ:

  • Как работать с узлами StaticBody2D.
  • Как удалить узлы из сцен с помощью queue_free().

Давайте создадим новую сцену с узлом Area2D в качестве корня. У него должны быть следующие дочерние элементы: AnimatedSprite2D, CollisionShape2D (с назначенным ему CircleShape2D) и узел Timer. Эти узлы позволят нам проверить, сталкивается ли столкновение с нашим игроком, и если это правда, он должен воспроизвести анимацию и удалить бомбу из нашей сцены. Если бомба не сталкивается с нашим игроком, она должна «самоуничтожиться» через несколько секунд.

Давайте назначим новый сценарий нашей сцене и сохраним его в папке Scripts.

Затем подключите к скрипту сигнал timeout() узлов Timer, а также сигнал body_entered() узлов Area2D.

Прежде чем мы приступим к кодированию, давайте настроим несколько анимаций. В нашем узле AnimatedSprite2D создадим новый ресурс SpriteFrames с двумя анимациями: «движение» и «взрыв».

Для вашей движущейся анимации перейдите к «res://Assets/Kings and Pigs/Sprites/09-Bomb/Bomb On (52x56).png» и назначьте все четыре кадра вашей анимации. Вы можете пока оставить зацикливание и FPS значениями по умолчанию.

Для анимации взрыва перейдите к «res://Assets/Kings and Pigs/Sprites/09-Bomb/Boooooom (52x56).png» и назначьте все шесть кадров своей анимации. Вы можете пока оставить зацикливание и FPS значениями по умолчанию.

В вашем скрипте давайте сделаем нашу анимацию движения нашей анимацией по умолчанию, когда Бомба входит в игровую сцену.

### Bomb.gd 
extends Area2D

#default animation on spawn
func _ready():
    $AnimatedSprite2D.play("moving")

В нашей func _on_body_entered(body):, нам нужно проверить, входит ли игрок в форму столкновения нашей сцены с бомбой, и если это так, мы должны воспроизвести нашу анимацию взрыва и запустить наш таймер. Таймер позволит нам иметь задержку анимации в 1 секунду перед удалением нашей бомбы из нашей сцены.

### Bomb.gd 

extends Area2D

#default animation on spawn
func _ready():
    $AnimatedSprite2D.play("moving")
    
func _on_body_entered(body):
    #if the bomb collides with the player, play the explosion animation and start the timer
    if body.name == "Player":
        $AnimatedSprite2D.play("explode")
        $Timer.start()

Затем в нашей функции timeout() нам нужно удалить сцену из дерева игровых сцен. Чтобы удалить узел из нашей сцены, мы используем объект queue_free(). Это наиболее стандартизированный способ удаления или уничтожения объектов из деревьев сцен. Существует также free(), основное различие между ними в том, что queue_free() вызывается в следующем кадре. Мы удалим нашу сцену с бомбой только в том случае, если сцена с бомбой действительна (то есть существует).

### Bomb.gd 

extends Area2D

#older code

#remove the bomb from the scene only if the Bomb exists
func _on_timer_timeout():
    if is_instance_valid(self):
        self.queue_free()

Теперь, если вы запустите основную сцену и создадите экземпляр Бомбы, она должна взорваться и удалиться со сцены, если игрок столкнется с ней.

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

Мы можем сделать это с помощью новой сцены, которая будет служить нашей стеной, или мы можем сослаться на наш узел Tilemap «Уровень» как на тело. Это означает, что если бомба столкнется с тайлами на карте тайлов уровня, она должна взорваться. Недостатком этого является то, что вам нужно быть очень осторожным при создании пути, так как любое столкновение с вашей Tilemap взорвет бомбу. Я покажу вам оба пути.

Вариант 1. Взорвать бомбу с помощью Tilemap

Чтобы взорвать бомбу, если она столкнется с нашим узлом «Level» Tilemap в наших сценах Main (и Main_2), мы можем просто расширить нашу существующую функциональность бомбы следующим образом:

### Bomb.gd 

#older code

func _on_body_entered(body):
    #if the bomb collides with the player, play the explosion animation and start the timer
    if body.name == "Player":
        $AnimatedSprite2D.play("explode")
        $Timer.start()
        
    #if the bomb collides with our Level Tilemap (floor and walls). 
    if body.name == "Level":
        $AnimatedSprite2D.play("explode")
        $Timer.start()

Теперь каждый раз, когда бомба сталкивается с тайлом на узле уровня, она должна взорваться. Помните, что бомба взорвется только в том случае, если она столкнется с вашими стенами или полом — любой плиткой, которой вы назначили столкновения. Ваш фон и украшения должны быть в безопасности. Переместите свою бомбу на плитку, чтобы увидеть, работает ли это.

Вариант 2. Взрыв бомбы с использованием сцены столкновения

Если вы хотите, чтобы ваша бомба взорвалась только тогда, когда она достигнет определенных областей, вместо этого вам придется создать новую сцену. Создайте новую сцену с узлом StaticBody2D в качестве корня и добавьте к нему узел CollisionShape2D. Вы можете сделать форму столкновения RectangeShape2D и перетащить ее вниз, чтобы она была длинной. Узел StaticBody2D — это физическое тело для 2D-физики, которое является статическим. Это полезно для полов, стен, пикапов и, в нашем случае, столкновений. Наш узел Area2D в нашей сцене Bomb сможет сталкиваться с узлом StaticBody2D.

Переименуйте корень в «Стена» и сохраните свою сцену в папке «Сцены».

Теперь просто добавьте сцену стены в основную сцену. Вы можете изменить масштаб стены по осям x и y с помощью инструмента Scale Mode. Поместите эту стену там, где вы хотите, чтобы ваши зоны взрыва были. Таким образом, вы можете сделать стену любого размера. Для меня это будет отправной точкой нашей сцены.

В нашем скрипте теперь мы можем проверить, сталкивается ли бомба со Стеной. Мы будем использовать метод строки begins_with, чтобы проверить, начинается ли имя со слова «Стена». Поэтому, если мы несколько раз скопируем нашу сцену Стены в нашу Главную сцену, она взорвется, даже если имя будет «Стена», «Стена2», «Стена_x» и т. д.

### Bomb.gd 

#older code

func _on_body_entered(body):
    #if the bomb collides with the player, play the explosion animation and start the timer
    if body.name == "Player":
        $AnimatedSprite2D.play("explode")
        $Timer.start()
        
    #if the bomb collides with our Wall scene, explode and remove
    if body.name.begins_with("Wall"):
        $AnimatedSprite2D.play("explode")
        $Timer.start()

Теперь, если вы поместите свою бомбу в область своей стены и запустите свою сцену, она должна взорваться!

Если у вас есть несколько стен, вы можете организовать их в узле Node2D.

Ваш окончательный код должен выглядеть как этот.

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

Сейчас самое время сохранить ваш проект и сделать резервную копию вашего проекта, чтобы вы могли вернуться к этой части, если возникнут какие-либо ошибки, нарушающие работу игры. Вернитесь и повторите то, что вы узнали, прежде чем продолжить серию, и как только вы будете готовы, увидимся в следующей части!

Следующая часть серии руководств

Учебная серия состоит из 24 глав. Я буду публиковать все главы в отдельных ежедневных частях в течение следующих нескольких недель. Вы можете найти обновленный список ссылок на учебники для всех 24 частей этой серии на моем GitBook. Если вы еще не видите ссылку, добавленную к части, это означает, что она еще не опубликована. Кроме того, если будут какие-либо будущие обновления серии, мой GitBook будет местом, где вы сможете быть в курсе всего!

Поддержите серию и получите ранний доступ!

Если вам нравится эта серия и вы хотите поддержать меня, вы можете пожертвовать любую сумму моему магазину KoFi или купить оффлайн PDF, в котором вся серия собрана в одном буклете, который можно взять с собой!

Брошюра дает вам пожизненный доступ к полной автономной версии брошюры «Изучайте Godot 4, создавая двухмерный платформер» в формате PDF. Это 451-страничный документ, содержащий все учебные пособия из этой серии в последовательном формате, а также вы получите от меня специальную помощь, если вы когда-нибудь застрянете или вам понадобится совет. Это означает, что вам не нужно ждать, пока я опубликую следующую часть серии руководств на Dev.to или Medium. Вы можете просто двигаться дальше и продолжать обучение в своем собственном темпе — в любое время и в любом месте!

Эта книга будет постоянно обновляться для исправления недавно обнаруженных ошибок или устранения проблем совместимости с более новыми версиями Godot 4.