# 3. Сцена игрового поля
Table of Contents
3. Сцена игрового поля
Цель
Визуально зафиксировать компоновку игрового экрана из текстового описания: верхняя полоса с очками игрока и компьютера по краям и блоком «следующие три шара» по центру, основная область под поле 8×16, тёмный космический фон со звёздами — без полной игровой логики перемещений и очков (они запланированы на следующие шаги плана).
Описание выполненной работы
Дальнейший текст объясняет, как собран экран партии на Godot 4.5 в режиме портретного окна 720×1280, почему выбраны именно перечисленные узлы и что сознательно отложено до шага с правилами игры.
Соответствие макета текстовому описанию
В docs/description.md отдельным блоком перечислены ожидания к игровому полю: счёт игроков по краям верхней зоны, по центру — три следующих шара, основное поле 8 по горизонтали на 16 по вертикали, общий фон — тёмное звёздное небо. Эти пункты переведены в иерархию узлов без добавления игровых правил: счёт пока всегда показывает нули, а шары на поле расставлены случайным образом только для превью верстки и будут заменены состоянием партии на шаге 4.
Такое разделение обязанностей между шагами плана упрощает отладку: если что‑то «поехало» по отступам или пропорциям сетки, это видно сразу и не смешивается с ошибками поиска пути или начисления очков.
Каркас сцены и порядок отрисовки
Корневой узел сцены — Control, растянутый на весь безопасный прямоугольник вида. Первым потомком идёт ColorRect с материалом ShaderMaterial, проигрывающим простой canvas‑шейдер звёзд. Он не участвует в логике ввода и помечен режимом игнорирования мыши/тача, чтобы не перехватывать события там, где поверх уже лежит колонка интерфейса.
Поверх фона расположен вертикальный VBoxContainer: узкая строка с кнопкой возврата в меню, затем PanelContainer с полупрозрачным StyleBoxFlat для верхней «шторки» HUD, затем растягивающийся MarginContainer с игровой сеткой. Такой порядок гарантирует читаемость подписей на звёздном фоне и повторяет привычное для мобильных игр расположение «меню назад сверху», игровые показатели чуть ниже, основное поле занимает оставшуюся высоту.
Почему сетке помогает AspectRatioContainer
Геометрически поле должно оставаться прямоугольником с соотношением сторон ширина к высоте, как 8 к 16, то есть 0.5. Если просто положить GridContainer на всю свободную высоту без ограничения по ширине, на узком экране клетки могут стать чрезмерно вытянутыми по вертикали, а шары будут выглядеть как овалы. Чтобы избежать этого без ручного подбора констант под каждый девайс, между полем и отступами вставлен AspectRatioContainer с ratio = 0.5 и режимом растягивания к родительскому прямоугольнику.
Внутри контейнера соотношения сторон находится CenterContainer, который центрирует сам GridContainer с восемью колонками. При изменении размеров области _aspect.resized вызывает функцию перерасчёта размеров ячеек: из доступной ширины и высоты вычитаются зазоры между клетками, затем берётся целочисленный размер стороны квадратной ячейки как минимум из двух оценок по осям. Это типичный приём для квадратных тайлов на полях «из клеток».
Отдельная сцена ячейки и заготовка под «планету»
Каждая клетка — экземпляр cell_view.tscn, тип которого дополнительно помечен директивой class_name CellView для удобства типизации в коде поля. Визуально клетка — Panel со скруглённым StyleBoxFlat и полупрозрачной рамкой; внутри лежит дочерний Panel будущего шара, изначально скрытый.
Метод show_ball(color) задаёт шару собственный плоский стиль с контрастной окантовкой и включает видимость. clear_ball() возвращает клетку в пустое состояние. NOTIFICATION_RESIZED поддерживает отступ между рамкой клетки и шаром пропорционально текущей стороне клетки, чтобы при масштабировании поля не приходилось вручную подгонять отступы в редакторе.
На шаге 3 для проверки композиции вызывается вспомогательная процедура _demo_visuals(), которая очищает клетки, затем случайным образом помещает ограниченное число цветных шаров из палитры «условных планет» солнечной системы и отдельно перекрашивает три превью в HUD. Комментарий в коде прямо предупреждает, что это временная заглушка до интеграции модели партии.
Верхняя панель и три превью
Центральная колонка HUD содержит подпись «Следующие» и горизонтальный ряд из трёх небольших Panel со скриптом PlanetPreview. Скрипт настраивает StyleBoxFlat так, чтобы при фиксированных минимальных размерах панель выглядела как круглая «иконка» планеты с лёгкой обводкой; обработчик resized синхронизирует радиус скругления с текущей стороной виджета.
Левый и правый столбцы — вертикальные VBoxContainer с подписью роли и крупной метрикой счёта (Label с нулём). Выравнивание текста компьютера к правому краю выполняется стандартным свойством horizontal_alignment, чтобы визуально балансировать колонку относительно центральных превью.
Звёздный фон на стороне CanvasItem
Шейдер starfield_bg.gdshader работает в режиме canvas_item и строит звёзды процедурно от координат UV с индексируемым шумом без текстурных выборок. Небольшое медленное мерцание получают через функцию времени TIME, но без физически корректной астрономии — задача художественная и дешевая по производительности для мобильного рендера.
Цвет неба задаётся uniform со значением по умолчанию близким к использованному в интерфейсе тёмно‑синему фону; при желании позже можно вынести этот параметр в ресурс темы или настройку качества графики.
Переходы между сценами меню и партии
Кнопка «Играть» на титульном экране теперь вызывает change_scene_to_file("res://scenes/game_board.tscn"), возвращая поведение к обычному для Godot паттерну полной замены активного дерева сцен. Кнопка «Меню» на игровом экране выполняет обратный переход на main.tscn, где по‑прежнему создаётся меню как дочерний экземпляр после шага 2.
Файл game_placeholder.tscn может оставаться в репозитории как исторический артефакт первых итераций, но из активного потока навигации он убран, чтобы не плодить дублирующие входные точки в игру.
Что сознательно не делалось на этом шаге
Правила из описания — один ход как одно перемещение, цепочки удалений по линиям, очки 3 / 6 / 9 …, ограничение на свободные клетки и путь через пустые клетки, завершение партии при отсутствии ходов — не реализованы в этой сцене. Также отсутствуют подсказки под палец, анимации появления шаров и звуковые отклики интерфейса: их логичнее добавить после того, как ячейки начнут получать осмысленные состояния из одной модели данных на шаге 4.
При переходе к логике имеет смысл завести отдельный скрипт match_controller.gd или аналог, который будет держать массив состояний размером COLS × ROWS, очередь следующих цветов и ссылки на ScoreHuman/ScoreAI, не смешивая вычисления с чисто визуальными узлами ячеек.
Практическая самопроверка после сборки
Запустите проект из редактора в портретном окне: убедитесь, что сетка действительно содержит 128 активных ячеек (проверка «на глаз» по столбцам и строкам), что три превью в центре HUD отображаются одновременно, что звёзды видны по краям полупрозрачной панели счёта и что переходы «Меню ↔ Играть» не оставляют «зависших» узлов из предыдущей сцены.
На реальном Android‑устройстве дополнительно стоит проверить, что верхняя панель не пересекается с системным вырезом статус‑бара — при необходимости следующие шаги могут использовать SafeArea через отступы DisplayServer или обёртку из документации по адаптивному UI Godot.
Ссылка на проект: Third Planet
Ссылка на игру: Google Play Rustore