Table of Contents

16. Тени

Цель

Добавить объём и отделение слоёв интерфейса от фона без тяжёлых текстур: проект уже построен на Panel и StyleBoxFlat, поэтому логично использовать встроенные поля shadow_color, shadow_size и shadow_offset там, где элемент выглядит «липким» к звёздному небу.

Описание выполненной работы

Почему именно StyleBoxFlat, а не отдельные спрайты теней

В Godot 4 для Control узлов самый предсказуемый способ получить мягкую тень без дополнительных текстур и без включения сложных CanvasLayer эффектов — параметры у StyleBoxFlat. Они работают при любом масштабе интерфейса (режим canvas_items stretch у проекта), корректно обрезаются скруглениями corner_radius и не требуют править код game_board.gd: всё остаётся в .tscn и шейдере планеты.

Отдельные DropShadow через ColorRect или дублирование узлов под каждую кнопку удорожили бы сцену и усложнили анимации масштаба клеток из шага 15 — тень StyleBox масштабируется вместе с Panel.

Ячейки поля (cell_view.tscn)

Стиль StyleBoxFlat_cell дополнен полями:

  • shadow_color с умеренной альфой (около 0.42) на чёрном, чтобы на градиентном космическом фоне тень не давала серую «кашу»;
  • shadow_size порядка 5 пикселей для мобильного DPI;
  • shadow_offset со смещением вниз (Vector2(1, 4)), чтобы свет всё ещё читался как «сверху-слева», согласованный с освещением в planet_ball.gdshader.

При удалении линии масштаб и альфа клетки анимируются шагом 15 — тень Panel остаётся частью того же узла и не «оторвана» от шара.

Игровой HUD, баннер и результат (game_board.tscn)

Три ключевых StyleBoxFlat:

  1. StyleBoxFlat_hud — основная верхняя панель со счётом и превью: более крупная тень (shadow_size = 8) и смещение (0, 5), чтобы панель визуально перекрывала фон и слегка парила над полем.
  2. StyleBoxFlat_banner_slot — нижний слот под рекламный баннер: тень чуть мягче (6 и 0.38 альфы), чтобы не конкурировать с HUD по контрасту.
  3. StyleBoxFlat_result — карточка итога: самая выраженная тень (shadow_size = 14, shadow_offset (0, 8), слегка синеватый shadow_color), чтобы модальный слой читался поверх затемнения Dim.

Дополнительно добавлен общий StyleBoxFlat_toolbar_btn для компактных кнопок на поле («Меню») и «В главное меню» в оверлее — один стиль упрощает сопровождение.

Главное меню и модальные панели (title_screen.tscn)

Фон титула переведён на шейдерный слой (шаг 17), из‑за чего элементы управления должны быть ещё более отделены от ярких звёзд и туманности:

  • основным кнопкам («Играть», «Новая игра», «Звук», «Правила», «Выход») заданы StyleBoxFlat_menu_btn и StyleBoxFlat_menu_btn_hover с тенью и контрастной обводкой;
  • Закрыть в настройках и справке используют более плоский StyleBoxFlat_overlay_btn — меньше тени, чтобы не спорить с рамкой родительской PanelContainer;
  • у модальных панелей (настройки / правила) усилены параметры тени базового StyleBoxFlat_settings_panel.

Цвета текста кнопок переопределены через theme_override_colors, чтобы белый шрифт не «выжигался» на светлом hover.

Шейдер планеты: контактное затемнение

Отдельная большая «капля» тени под каждым шаром потребовала бы второго TextureRect или усложнила бы CellView. Вместо этого в planet_ball.gdshader после расчёта rgb из освещения добавлен множитель по функции occlude от комбинации uv.y (положение по вертикали в текстуре шара) и радиуса r. Нижняя область шара слегка темнеет (коэффициент до ~0.82), создавая ощущение контакта с поверхностью клетки и согласуясь с тенью Panel под ним.

Это не заменяет полноценный каст-тень под объектом на произвольном фоне, но для регулярной сетки ячеек визуально стабильно и дёшево по GPU.

Настройка и типичные ошибки

Слишком большая shadow_size на маленьких клетках может дать размытый прямоугольник шире зазора между ячейками — если появится грязь между рядами, уменьшите shadow_size или альфу shadow_color. Если тени не видны на Android, проверьте, что масштаб интерфейса не опускает альфу стилей до нуля через тему проекта.

При добавлении новых Panel на игровой сцене копируйте параметры тени с ближайшего родственника (HUD или banner_slot), чтобы визуальная иерархия сохранялась.

Что можно добавить позже без поломки архитектуры

  • Отдельный Theme ресурс для всего приложения с общими StyleBox для кнопок разных уровней (primary / secondary / danger).
  • Лёгкий shader для DropShadow только под CanvasLayer результатов, если понадобится цветное свечение вместо чёрной тени StyleBox.
  • Пер-устройственный множитель shadow_size через GDScript после чтения DPI — это уже связано со шагом адаптивной вёрстки в плане.

Отладка в редакторе и типичные сценарии регресса

Если после изменения темы проекта тени «пропали», проверьте в Project Settings → GUI → Theme не переопределён ли custom темой без поддержки StyleBoxFlat. Иногда разработчик подключает готовый Theme из ассет-стора, который задаёт StyleBoxEmpty для кнопок — тогда локальные theme_override_styles на узле сохраняют приоритет, но Panel без переопределения может потерять стиль.

При экспорте под Vulkan vs GLES3 отличаться должны только шейдеры, не StyleBox; если видите расхождение между редактором и устройством, чаще виноват разный DPI и масштаб системных шрифтов Android — попробуйте stretch режим canvas_items с display/window/stretch/scale по умолчанию проекта и не смешивайте control масштаб дерева со viewport масштабом без нужды.

Для регрессионного теста пройдите короткий чеклист: главное меню (все кнопки и модалки), партия с заполнением нижних рядов доски (тени ячеек не должны сливаться в сплошную кромку), экран результата с длинным подзаголовком (карточка не должна обрезать тень клипом родителя — при проблемах включите clip_contents только у необходимых предков или добавьте MarginContainer).

Связь с шагом 17 по восприятию глубины

После усложнения фона процедурным небом контраст между Control и фоном мог бы упасть; тени шага 16 восстанавливают иерархию слоёв. При последующей замене фона на статическую иллюстрацию имеет смысл заново подобрать shadow_color в сторону чуть более синего или фиолетового оттенка, чтобы тень не выглядела «грязной» на тёплом художественном фоне — достаточно правки StyleBox без изменения GDScript.

Ссылка на проект: Third Planet

Ссылка на игру: Google Play Rustore

Next: 17. Фон игрового поля и меню
Аватар автора

Спасибо, что прочитали статью. Посмотрите другие материалы в архиве, там много практических разборов по разным технологиям.


godot Series