Как события запускают скрипты: флажок, щелчок и передача сигналов

Scratchобновлено 07.10.20269 мин чтения

События в Scratch — это жёлтые блоки-шапки, с которых начинается любой скрипт: «когда щёлкнут по флажку», «когда клавиша нажата», «когда спрайт нажат». Сообщения — особый вид событий: один спрайт «передаёт» сигнал, а все, у кого есть блок «когда я получу», начинают действовать. Так спрайты договариваются между собой и переключают сцены.

Что такое событие в Scratch

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

Скрипт без шапки сам по себе не запустится никогда — разве что если щёлкнуть по нему мышкой в области скриптов. Поэтому первое, что делает новичок, — ставит наверх «когда щёлкнут по флажку». Дальше выясняется, что шапок может быть много, и каждая запускает свой скрипт независимо. Один спрайт одновременно реагирует на флажок, на пробел и на щелчок по себе.

Карен Бреннан и Митчел Резник из MIT Media Lab выделили события и параллельность в отдельные концепции вычислительного мышления[1]: ребёнок, собирающий игру в Scratch, привыкает думать не «программа идёт сверху вниз», а «что произойдёт, когда случится вот это». Такой стиль называется событийно-ориентированным программированием, и на нём построены почти все приложения с кнопками.

В статье Maloney и соавторов, где описано устройство среды, скрипты под шапками событий показаны как основной способ сделать проект интерактивным: каждая реакция живёт в своём коротком скрипте, а не в одной длинной программе[2]. Митчел Резник в книге о подходе Lifelong Kindergarten связывает это с игрой: ребёнок добавляет героям реакции одну за другой и сразу проверяет, что получилось[3]. Для школьника это значит простую вещь — большой проект можно строить по кусочку, и каждый кусочек работает отдельно.

Блоки-шапки: все события по порядку

Все события в Scratch собраны в жёлтой категории — это 8 блоков: 6 шапок, которые запускают скрипты, и 2 блока передачи сообщений, которые ставят внутрь скриптов.

БлокКогда срабатываетПример использования
«когда щёлкнут по флажку»Нажат зелёный флажок над сценойСтарт игры, сброс очков
«когда клавиша … нажата»Нажата выбранная клавиша или любаяПрыжок по пробелу
«когда спрайт нажат»Щелчок мышью по спрайтуКнопка «Играть»
«когда фон меняется на …»Сцена переключилась на выбранный фонНачало нового уровня
«когда громкость > 10» или «таймер > 10»Значение превысило порогХлопок в ладоши будит кота
«когда я получу …»Кто-то передал это сообщениеВраги замирают по сигналу
«передать …»Отправляет сообщение и сразу идёт дальшеСигнал «победа»
«передать … и ждать»Отправляет и ждёт, пока все получатели закончатДиалог по очереди

У сцены вместо «когда спрайт нажат» есть «когда сцена нажата». Набор шапок одинаков в онлайн-редакторе и в офлайн-версии от MIT, так что инструкции подходят для обоих вариантов. Блок «когда я начинаю как клон» тоже похож на шапку, но лежит в категории «Управление» и относится к клонам.

Флажок и стартовые настройки

Зелёный флажок — это главное событие проекта: по нему запускаются сразу все скрипты с блоком «когда щёлкнут по флажку» во всех спрайтах и на сцене, поэтому под ним собирают стартовые настройки.

Что обычно ставят под флажком: стартовую позицию «перейти в x: y:», направление, первый костюм, «показаться», обнуление очков и жизней, стартовый фон. Если этого не сделать, проект при повторном запуске начнёт с того состояния, в котором его остановили: кот окажется у края, монеты останутся спрятанными, счёт продолжится. Событие флажка в Scratch срабатывает при каждом нажатии, поэтому хорошее правило — после каждой правки запускать проект флажком дважды подряд и проверять, одинаково ли он стартует.

Клавиши и щелчки мышью

Блок «когда клавиша … нажата» запускает скрипт при каждом нажатии выбранной клавиши, а «когда спрайт нажат» — при щелчке по спрайту; оба удобны для разовых действий вроде прыжка или нажатия кнопки.

когда спрайт нажат
играть звук [Pop]
передать [старт]
спрятаться

Это кнопка «Играть» на заставке: по щелчку она щёлкает, передаёт сигнал «старт» и исчезает. Для плавного движения стрелками событие клавиши подходит хуже: при удержании срабатывает автоповтор клавиатуры, и герой двигается рывками. Плавное управление делают циклом с проверкой «клавиша … нажата?», как показано в уроке про движение спрайтов стрелками.

Сообщения: «передать» и «когда я получу»

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

Новое имя создаётся в выпадающем списке блока: пункт «Новое сообщение». Называйте сигналы по смыслу: «старт», «победа», «уровень 2», «кот договорил». Сообщение не адресовано кому-то конкретно — его слышат все, включая отправителя. Этим события в Scratch отличаются от вызова функции в текстовом языке, где вызывающий точно знает, кого зовёт. Если на сигнал никто не подписан, ничего не произойдёт, и ошибки тоже не будет. Именно через сообщения в проектах чаще всего проявляется параллельность, которую Brennan и Резник описывают как отдельную концепцию: от одного сигнала стартуют сразу несколько скриптов.

— спрайт «Кот» —
когда щёлкнут по флажку
говорить [Привет, Пёс!] 2 секунд
передать [кот договорил]

— спрайт «Пёс» —
когда я получу [кот договорил]
говорить [Гав! Привет!] 2 секунд

Так строится диалог: пёс отвечает ровно тогда, когда кот закончил фразу. Без сообщения пришлось бы подбирать паузу «ждать 2 секунд» у пса, и при любой правке реплики всё бы рассыпалось. Сообщения — главный инструмент синхронизации в мультфильмах; пошаговый пример — в статье о мультфильме в Scratch.

«Передать и ждать»: порядок действий

Блок «передать … и ждать» отправляет сообщение и останавливает текущий скрипт, пока все получатели не закончат свои скрипты; обычный «передать» идёт дальше сразу.

Разница видна на заставке игры. Если сцена делает «передать [показать правила] и ждать», а потом «переключить фон на Уровень 1», то фон сменится только после того, как спрайт-ведущий дочитает правила. С обычным «передать» фон сменился бы мгновенно, и правила никто бы не увидел. Но будьте осторожны: если получатель запускает «повторять всегда», ожидание не закончится никогда.

Смена сцен и уровней

Сцены и уровни переключают 2 способами: сменой фона с блоком «когда фон меняется на …» или сообщением вроде «уровень 2», которое получают все участники.

— сцена —
когда я получу [победа]
переключить фон на [Уровень 2]

— спрайт «Герой» —
когда фон меняется на [Уровень 2]
перейти в x: -200 y: -120
говорить [Новый уровень!] 2 секунд

Удобно, когда фон отвечает за «где мы», а сообщения — за «что случилось». Тогда каждый спрайт сам решает, как реагировать на новый уровень: герой встаёт на старт, враги ускоряются, музыка меняется. Тот же приём используют в викторинах, где каждый вопрос — свой фон, и в историях с несколькими сценами. Готовая игра с уровнями собрана в уроке про игру-лабиринт пошагово.

События в Scratch и функции в Python

Скрипт под шапкой «когда я получу» похож на функцию в Python: у него есть имя, и он выполняется, когда его «вызывают», а блок «передать» — это вызов сразу всех функций с таким именем.

def kot_govorit():
    print("Кот: Привет, Пёс!")

def pyos_otvechaet():
    print("Пёс: Гав! Привет!")

podpischiki = [kot_govorit, pyos_otvechaet]
for funkciya in podpischiki:
    funkciya()

Здесь список podpischiki играет роль сообщения: цикл по очереди вызывает всех, кто на него подписан. Отличие в том, что в Scratch получатели работают параллельно, а этот пример вызывает их по одному. Как устроены функции в тексте, объясняет статья про функции в Python.

Когда сообщения мешают

Сообщения мешают, когда их становится слишком много или когда ими заменяют то, что проще сделать иначе. Вот 4 признака.

  • Больше 15 сообщений в проекте. Запутаться в сигналах легко; часть заменяет смена фона или переменная.
  • Сигнал передаётся 30 раз в секунду. «Передать» внутри быстрого цикла перезапускает скрипты получателей, и они не успевают доработать.
  • Сообщение ради 1 спрайта, который его же и шлёт. Проще поставить нужные блоки прямо в скрипт.
  • Реакция на касание. Касание проверяют условием в цикле; события «когда коснулся» среди 8 жёлтых блоков нет.

Миф: «Сообщение получает только тот спрайт, которому его отправили». Это не подтверждается: адресата у сообщения не существует, его слышат все спрайты и сцена.

Миф: «Скрипты запускаются по очереди, в порядке спрайтов в панели». На деле все скрипты с одной шапкой стартуют одновременно и работают параллельно, поэтому порядок нужно задавать сообщениями.

Чего делать нельзя

Нельзя подбирать синхронизацию паузами «ждать 3 секунд» там, где нужен сигнал: любая правка реплики разрушит мультфильм. Вот и другие правила.

  • Нельзя называть сигналы «сообщение1», «сообщение2» — через день не вспомнить, что каждый означает.
  • Не стоит ставить «передать» внутрь «повторять всегда» без паузы или условия.
  • Не следует использовать «передать и ждать», если получатель запускает бесконечный цикл.
  • Не стоит дублировать стартовые настройки в нескольких скриптах под флажком одного спрайта.
  • Нельзя оставлять скрипт без шапки и ждать, что он сработает при запуске.

Источники

[1] Brennan K., Resnick M. New frameworks for studying and assessing the development of computational thinking // Proceedings of the 2012 Annual Meeting of the American Educational Research Association. Vancouver, 2012.

[2] Maloney J., Resnick M., Rusk N., Silverman B., Eastmond E. The Scratch Programming Language and Environment // ACM Transactions on Computing Education. 2010. Vol. 10, № 4. Article 16.

[3] Resnick M. Lifelong Kindergarten: Cultivating Creativity through Projects, Passion, Peers, and Play. Cambridge, MA: MIT Press, 2017.

Вопросы и ответы

Почему скрипт не запускается по флажку?

Проверьте, что шапка «когда щёлкнут по флажку» действительно соединена с блоками под ней, а не лежит рядом. Между ними не должно быть зазора.

Можно ли передать сообщение одному спрайту?

Напрямую нет: сигнал слышат все. Но реагируют только те, у кого есть шапка «когда я получу» с этим именем, — дайте её одному спрайту.

Как сделать реакцию на любую клавишу?

В выпадающем списке блока «когда клавиша … нажата» выберите вариант «любая».

Сколько шапок может быть у одного спрайта?

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

Что будет, если передать сигнал, на который никто не подписан?

Ничего: ошибки нет, просто никто не отреагирует. Это частая причина «молчащих» проектов — проверьте имя в шапке получателя.

Зачем нужны события, если есть «повторять всегда»?

Цикл постоянно опрашивает состояние, а событие срабатывает само, только когда нужно. Так проект проще читать, и он меньше нагружает компьютер.