Сейчас я расскажу о структуре программы godot Hierarchical Finite State Machine

Рассмотрим код и структуру туториала на Godot — Hierarchical Finite State Machine.

Главный игрок представляет собой дочерний узел типа CharacterBody2D. Внутрь него вложен узел Node, который, в свою очередь, содержит ещё шесть узлов Node.

Внутри CharacterBody2D также находятся:

AnimationPlayer

Sprite2D

Marker2D — относительно него расположено тело игрока; отсюда с помощью таймера и Node2D могут создаваться пули.

Дополнительные узлы Marker2D — один для управления мечом, другой для подключения сцены меча.

Кроме того, у персонажа есть CollisionPolygon2D для обработки столкновений и специальная метка для отображения текущего состояния.

 

Главные классы сцены персонажа

 

Основные скрипты здесь — state.gd и state_machine.gd. В state.gd присутствует сигнал finished. Он испускается при наступлении какого-либо события, например:

Stagger вызывается после Idle,

Move — после Idle,

Jump — после Idle.

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

Далее рассмотрим функцию _enter_tree() в скрипте state_machine.gd.

func _enter_tree() -> void:
if start_state.is_empty():
start_state = get_child(0).get_path()
for child in get_children():
var err: bool = child.finished.connect(_change_state)
if err:
printerr(err)
initialize(start_state)

Если в узле start_state ничего нет, в него добавляется первый дочерний узел — Idle. После этого запускается цикл по всем дочерним узлам, а именно по узлам типа Node: Idle, Move, Jump, Stagger, Attack, Die, которые вложены в узел StateMachine. Все сигналы finished этих узлов соединяются с методом _change_state. Рассмотрим подробнее этот метод.

func _change_state(state_name: String) -> void:
if not _active:
return
current_state.exit()

if state_name == "previous":
states_stack.pop_front()
else:
states_stack[0] = states_map[state_name]

current_state = states_stack[0]
state_changed.emit(current_state)

if state_name != "previous":
current_state.enter()

В этом методе изменяется узел текущего состояния — current_state, после чего испускается сигнал state_changed. Этот сигнал может использоваться для отображения текущего узла или для вызова сцены атаки (например, с помощью меча). Затем вызывается метод enter() у сцены текущего состояния — этот метод определён в файле state.gd.

Как показано на рисунке, в коде State.gd имеется сигнал finished. Он вызывается в любом месте наследуемых классов: Idle.gd, Move.gd, Jump.gd, Stagger.gd или Attack.gd. Этот сигнал инициирует вызов метода _change_state в StateMachine.gd, который, в свою очередь, испускается и связывается в player_state_machine либо с объектами атаки мечом, либо с выводом на экран текущего состояния.

Дополнительные элементы:

Сцена пуль: пули вылетают из игрока и генерируются по таймеру при нажатии на кнопку R.

Сцена меча: мечом можно ударить два раза, если часто нажимать на кнопку F.

Код игрока (player_controller): содержит функцию take_damage (не работает, поскольку в сцене нет второго врага), а также функцию set_dead, которая отключает физику игрока.

Переменная look_direction: используется для правильного позиционирования меча и пуль.

Сигнал direction_changed: испускается при изменении позиции игрока. Для пуль look_direction непосредственно задаёт направление полёта (direction).

WeaponPivot: сигнал direction_changed связывается с методом, управляющим углом вращения меча.

Конец.

Мы грубо и схематично рассмотрели программу Godot Hierarchical Finite State Machine. В следующих частях мы будем восстанавливать эту программу. Спасибо за внимание.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх