Подключение к сигналам
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 37 из 65.
connect() принимает функцию для выполнения в виде Callable. Укажи метод без скобок или напиши лямбда-функцию:
chest.opened.connect(_on_chest_opened) # метод этого скрипта
chest.opened.connect(quest_log.add_entry) # метод другого объекта
chest.opened.connect(func(): print("Creak!")) # лямбда-функцияGodot называет метод-обработчик: сначала _on_, затем отправитель, а потом сигнал: _on_chest_opened. К сигналу можно подключить множество функций, и они выполняются в том порядке, в котором были подключены.
Объект, который отслеживает сигнал, обычно подключается к нему самостоятельно в методе, получающем источник сигнала:
# quest_log.gd
class_name QuestLog
extends RefCounted
var chests_opened := 0
func track(chest: Chest) -> void:
if not chest.opened.is_connected(_on_chest_opened):
chest.opened.connect(_on_chest_opened)
func untrack(chest: Chest) -> void:
if chest.opened.is_connected(_on_chest_opened):
chest.opened.disconnect(_on_chest_opened)
func _on_chest_opened() -> void:
chests_opened += 1Подключать одну и ту же функцию к одному и тому же сигналу дважды — ошибка, как и отключать функцию, которая не подключена. Сначала проверьте это с помощью is_connected(). disconnect() прекращает прослушивание, и при следующем испускании сигнала эта функция уже не будет запущена.
Передай CONNECT_ONE_SHOT в качестве второго аргумента, и соединение удалится после первого вызова: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).
Лямбда сохраняет значение локальной переменной на момент создания лямбды. count += 1 внутри подключённой лямбды изменяет эту копию, а count в _ready() остаётся равным 0. Храни счётчик в переменной-члене объекта-обработчика, как это делает QuestLog.
Задание
ЛегкоНа стрельбище есть мишени, которые при попадании испускают сигнал hit. Напишите ScoreBoard, который будет на них подписываться:
watch(target)подключает сигналhitмишени к_on_target_hit. Повторная подписка на уже отслеживаемую мишень ничего не меняет.ignore(target)отключает сигнал. Отмена подписки на мишень, за которой не следят, ничего не меняет._on_target_hit()добавляет10кpointsи выводитHit! Score: N.
Повторная подписка или отмена подписки на мишень, за которой не следят, не должны приводить к ошибке, потому что любая ошибка провалит тест. Файл target.gd уже готов.
Предоставленный код считывает количество мишеней, затем команды, такие как watch 0, ignore 0 и shoot 0, и выводит итоговый счёт. Для двух мишеней и команд watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0 программа выводит:
Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20Ваш код нужно поместить в score_board.gd и target.gd. В main.gd находится предоставленный код ввода-вывода, и его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var board := ScoreBoard.new()
var targets: Array[Target] = []
for i in int(OS.read_string_from_stdin()):
targets.append(Target.new())
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
var target := targets[int(parts[1])]
if parts[0] == "watch":
board.watch(target)
elif parts[0] == "ignore":
board.ignore(target)
else:
print("Shot target ", parts[1])
target.shoot()
print("Final score: ", board.points)
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript