К карте
ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6
Склянки боцмана
0
Прогресс0 / 5
СДЕЛАЙ ПЕРВЫЙ ХОД

Нажми — и увидишь, что делает команда

Жми кнопки по очереди — это три настоящие команды.
ПЕРЕД СТАРТОМ
⏱ Сколько займёт
30–50 минут, 5 шагов. Каждый шаг заканчивается результатом на экране.
💻 Что нужно
Компьютер с Windows или macOS. Понадобится Godot — бесплатный, поставим на первом шаге. С телефона этот квест не проходится.
⏸ Если прервёшься
Ничего не потеряется: прогресс сохраняется на этом устройстве. Вернёшься — продолжишь с того же шага.
🎓 Чему научишься
предметы с эффектами · await и таймеры · здоровье
ШАГ 1 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6

Выпил — и всё изменилось

ЧТО ПРОИСХОДИТ
ЭПИЗОД 6Камбуз

В камбузе на полке стоят склянки боцмана: зелёная, красная, синяя. Подписаны углём.

«Красная лечит, зелёная даёт скорость на восемь секунд, синяя… синюю не трогай», — Клык убирает синюю в карман.

Скорость проходит сама. Значит, нужен кто-то, кто помнит время и вернёт всё обратно.

боцман Клык · старший на палубе
ЧТО ПОЛУЧИТСЯ
ЗАПИСЬ ГОТОВОЙ ИГРЫ
Выпил склянку — скорость выросла вдвое, и сразу поползла полоска. Кончилась — всё вернулось. Эффект на время, а не навсегда: в этом весь баланс.

Это записано в самом Godot — движок посчитал физику и нарисовал каждый кадр. К концу квеста такая же игра будет запускаться у тебя.

СНАЧАЛА — ПОСМОТРИ
ЖИВАЯ ЗАПИСЬ ДВИЖКА
Зелья меняют героя: одно увеличивает, другое ускоряет, третье подбрасывает выше. И всё это — на время. В ролике есть ещё полоска здоровья — её в квесте не строим, но собрать такую же ты сможешь сам.
Мастер Тео
Читать текстом
Зельевар, вечная сила — это скучно: выпил и играешь дальше. Интересно, когда сила даётся ровно на восемь секунд: игрок начинает торопиться, планировать и рисковать. Сегодня главное слово — await. Оно останавливает только твою функцию, а игра идёт своим ходом: герой бегает, крабы патрулируют. Потом функция просыпается ровно там, где заснула, и возвращает всё обратно. Соберёшь три склянки: рост, скорость и лечение.

Сегодня появится новая идея: эффект, который сам себя выключает.

ЗАДАНИЕ 1 · ЗЕЛЬЕ РОСТА
scripts/potion_size.gdGDSCRIPT
extends Area2D

func _on_body_entered(body: Node2D) -> void:
	if body.name == "Player":
		body.scale *= 2   # игрок вырастает вдвое
		queue_free()      # бутылочка выпита
Сцена зелья: Potion · Area2D, внутри — Sprite2D (картинка бутылки) и CollisionShape2D (круг). Скрипт вешается на Area2D, сигнал body_entered подключается во вкладке «Узел».

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

Запусти и выпей. Герой станет великаном — и не влезет в узкий проход. Уже геймдизайн: за силу приходится платить.

Если великан застрял в полу — так бывает, когда растягивают само физическое тело. Поставь 1.5 вместо 2 или растягивай только картинку: body.get_node("Sprite2D").scale *= 2.

ШАГ 2 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6

Эффект на время

МАСТЕР ТЕО · ГИЛЬДИЯ РАЗРАБОТЧИКОВ
Постоянные эффекты — скучно. Интересно, когда сила даётся на восемь секунд: игрок начинает торопиться, планировать, рисковать. Осталось научить бутылку считать время.

В Godot есть два способа подождать. Первый — узел Timer: кладёшь его внутрь зелья, в Инспекторе ставишь Wait Time = 8 и галочку One Shot, а в коде пишешь $Timer.start() и ждёшь await $Timer.timeout. Плюс: время видно и правится мышкой, без кода. Второй — слово await с get_tree().create_timer(8.0).timeout: узел не нужен, всё в одной строке. Мы пойдём вторым путём — он короче; но в финальном задании попробуй и первый.

ЗАДАНИЕ 2 · ЗЕЛЬЕ СКОРОСТИ
scripts/potion_speed.gdGDSCRIPT
extends Area2D

@export var boost: float = 100.0
@export var duration: float = 8.0

func _on_body_entered(body: Node2D) -> void:
	if body.name == "Player":
		body.speed += boost
		hide()                                        # спрятали бутылку
		$CollisionShape2D.set_deferred("disabled", true)
		await get_tree().create_timer(duration).timeout   # пауза — но игра идёт!
		body.speed -= boost                           # вернули как было
		queue_free()
await останавливает только эту функцию, а игра продолжает работать: герой бегает, враги патрулируют. Через восемь секунд функция просыпается ровно там, где заснула, и доигрывает остаток.

Обрати внимание: узел не удаляют сразу. Бутылку прячут, отключают её зону — а живёт она ещё восемь секунд, чтобы было кому вернуть скорость обратно.

И не забудь подключить сигнал body_entered у зелья: вкладка «Узел» → двойной клик → «Подключить». Как у монеты.

Почему нельзя написать queue_free() сразу после body.speed += boost?
Godot запрещает удалять узлы в этой функции
Узел исчезнет — и через восемь секунд некому будет вернуть скорость обратно
Игрок не успеет увидеть эффект
ШАГ 3 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6

set_deferred и другие грабли

СОВЕТ МАСТЕРА
ПОЧЕМУ НЕ ПРОСТО disabled = true
Пока Godot считает физику, менять формы столкновений на ходу нельзя — движок ругнётся красным. set_deferred("disabled", true) говорит: «выключи, но не сейчас, а как досчитаешь кадр». Это одна из тех вещей, которые невозможно угадать — их просто надо знать.
НАЙДИ ОШИБКУ
scripts/potion_jump.gdнажми на строку с ошибкой
1extends Area2D
2
3@export var boost: float = 150.0
4@export var duration: float = 8.0
5
6func _on_body_entered(body: Node2D) -> void:
7 if body.name == "Player":
8 body.jump_force += boost
9 queue_free()
10 await get_tree().create_timer(duration).timeout
11 body.jump_force -= boost
Зелье прыжка работает вечно: эффект не проходит.

Зелье прыжка работает вечно — эффект не проходит. Найди строку-виновницу.

ЭКСКУРС
КАК В НАСТОЯЩИХ ИГРАХ

Зелья, кулдауны и честность

В Blox Fruits, Dota, Genshin — везде одно и то же: способность работает, потом ждёт. Это и есть баланс.

Без ожидания сильная вещь ломает игру: нажимай без конца и побеждай. С ожиданием появляется выбор — потратить сейчас или приберечь.

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

ШАГ 4 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6

Здоровье и лечение

ЗАДАНИЕ 3 · ЗЕЛЬЕ ЛЕЧЕНИЯ
scripts/potion_health.gdGDSCRIPT
extends Area2D

@export var heal: int = 30

func _on_body_entered(body: Node2D) -> void:
	if body.name == "Player":
		GameManager.health = min(GameManager.health + heal, 100)
		queue_free()
min() выбирает меньшее из двух. Без неё здоровье уползёт за сотню — а сотня у нас максимум. Такие «ограничители» ставят везде, где число может убежать.

Здоровье живёт в GameManager — значит, переживёт переход на следующий уровень. Показать его на экране просто: ещё один Label по образцу счётчика монет из третьего квеста, с текстом "HP: " + str(GameManager.health). А по-настоящему здоровье пригодится в 3D-экспедиции.

Здоровье 90, зелье лечит на 30. Сколько станет?
120
100
90
ШАГ 5 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 6

Своя алхимия

НАСТОЯЩИЙ ЭКРАН GODOT — КУДА НАЖИМАТЬ
ТВОЙ ЭКРАН GODOT — КУДА НАЖИМАТЬнажми на кружок — покажу место
Окно редактора
  • 1Плюс — собери бутылку из узловКорень зелья — Area2D: сквозь него проходят, а он замечает. Внутрь Sprite2D с картинкой бутылки и CollisionShape2D с кругом. Про Timer помни: время можно считать либо узлом Timer с галочкой One Shot, либо строкой await прямо в коде — в этом квесте код ждёт через await, значит второй узел уже не нужен.
  • 2Дерево — монета и зелье устроены одинаковоНа кадре Coin собрана ровно по рецепту зелья: Area2D, а внутри картинка и форма. Выдели её, нажми Ctrl+D — получишь копию, переименуй в PotionSpeed и поменяй картинку. Так делают все: новый предмет проще склонировать из готового, чем собирать с нуля.
  • 3Здесь появятся boost и durationТак выглядят поля из @export: на кадре это Speed и Jump Force героя. Напишешь в скрипте зелья @export var boost: float = 100.0 и @export var duration: float = 5.0 — получишь на этом же месте две крутилки. Слишком сильное зелье ломает уровень, слишком слабое не замечают: середину ищут вот тут, не открывая код.
  • 4Ниже по списку — цвет бутылки ModulateНа кадре Инспектор виден только до раздела Collision. Modulate живёт дальше: крути колесом внутри панели до раздела CanvasItem → Visibility. Дай каждому виду зелья свой цвет — игрок должен узнавать склянку издалека, не читая подписей.
  • 5Запуск — и выпей своё зельеПроверяй с секундомером: скорость выросла, через пять секунд вернулась обратно. Не вернулась — почти всегда одно и то же: queue_free() стоит выше строки await. Бутылка исчезла раньше, чем проснулся таймер, и возвращать эффект стало некому.
Отмечено:0 из 5

Это настоящий экран Godot 4.7 на русском — такой же откроется у тебя. Слева панель «Сцена» с деревом узлов и «Файловая система», в центре 2D-вьюпорт с линейками, справа «Инспектор». Нажимай на кружки по порядку: метка покажет место, строка ниже объяснит, зачем оно. Отмечай пройденное — прогресс сохранится.

МАСТЕР ТЕО · ГИЛЬДИЯ РАЗРАБОТЧИКОВ
Экспедиция закрыта. Твой платформер умеет всё, что умеет настоящий: физику, врагов, стрельбу, предметы с эффектами, здоровье, счёт, уровни. Дальше будет интереснее — мы уйдём в третье измерение.
Мастер Тео
Читать текстом
Экспедиция «Абордаж» закрыта. Ты сделал эффекты на время — то, что в играх зовут кулдауном: способность сработала, дальше ждёт. Именно из этого ожидания и рождается выбор игрока: потратить сейчас или приберечь. Дальше твой мир перестанет быть плоским — уходим в третье измерение, к рельефу, солнцу и теням.

Задание Гильдии перед дорогой: собери комнату испытаний — маленький уровень, где нужно правильно выпить три зелья по очереди, иначе не пройти. Такие головоломки любят все.

Поднимай флаг.

Экспедиция закрыта!

Зелья, таймеры, временные эффекты и здоровье — уровень стал живым. Печать АЛХИМИК ГИЛЬДИИ.

Что дальше. Утром туман сошёл, и стало видно: за проливом — ещё один остров. Настоящий, с холмами.

🏅 Забрать диплом Следующий квест: Остров за туманом Следующая экспедиция: третье измерение
🔒

Этот остров ещё закрыт

Сначала пройди предыдущий квест — хотя бы просмотри все шаги.

⚑ Экспедиционный режим