Что такое событие в 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.
Вопросы и ответы
Почему скрипт не запускается по флажку?
Проверьте, что шапка «когда щёлкнут по флажку» действительно соединена с блоками под ней, а не лежит рядом. Между ними не должно быть зазора.
Можно ли передать сообщение одному спрайту?
Напрямую нет: сигнал слышат все. Но реагируют только те, у кого есть шапка «когда я получу» с этим именем, — дайте её одному спрайту.
Как сделать реакцию на любую клавишу?
В выпадающем списке блока «когда клавиша … нажата» выберите вариант «любая».
Сколько шапок может быть у одного спрайта?
Сколько угодно, и даже одинаковых. Все скрипты под одной и той же шапкой запустятся одновременно.
Что будет, если передать сигнал, на который никто не подписан?
Ничего: ошибки нет, просто никто не отреагирует. Это частая причина «молчащих» проектов — проверьте имя в шапке получателя.
Зачем нужны события, если есть «повторять всегда»?
Цикл постоянно опрашивает состояние, а событие срабатывает само, только когда нужно. Так проект проще читать, и он меньше нагружает компьютер.