
Возможно, вы уже читали о конкурсе Flutter Puzzle Hack и думаете о том, как проявить максимум творческих способностей. И мы вам в этом поможем, рассказав о том, как структурирована кодовая база нашего примера головоломки. Подробностями делимся к старту авторского курса по веб-разработке на Python.
Архитектура
В представленном исходном коде многослойная архитектура для управления состоянием реализуется с помощью flutter_bloc. Блоки помогают управлять всем — от игровой логики до настройки тем.
Все состояния управляются согласованно: чтобы изменить логику головоломки, нужно только найти и обновить соответствующий блок. Кнопки сброса и перемешивания, таймера и обратного отсчёта — тоже отдельные блоки, которые можно расположить по вашей задумке: может быть, сделать песочные часы для таймера? Или шикарно стилизовать перемешивание?
Обратите внимание: вся игровая логика находится в одном блоке PuzzleBloc, который изменяется по таким событиям, как нажатие на один из 15 квадратиков и его перемещение с помощью события TileTapped, а также полный сброс головоломки по событию PuzzleReset. Состояние головоломки изменяется при каждом изменении в игре:
class PuzzleBloc extends Bloc<PuzzleEvent, PuzzleState> { PuzzleBloc(this._size, {this.random}) : super(const PuzzleState() { on<PuzzleInitialized>(_onPuzzleInitialized); on<TileTapped>(_onTileTapped); on<PuzzleReset>(_onPuzzleReset); } void _onPuzzleInitialized( PuzzleInitialized event, Emitter<PuzzleState> emit, ) {...} void _onTileTapped( TileTapped event, Emitter<PuzzleState> emit, ) {...} void _onPuzzleReset( PuzzleReset event, Emitter<PuzzleState> emit, ) {...} }
Настройка темы
В примере кода головоломки есть две темы: Simple и Dashatar. Их можно взять за основу для собственных настроек или начать с нуля — реализация зависит от вас! Творческий подход можно проявить в настройке тем головоломки.

В демо всё происходит в верхней части PuzzlePage. Достаточно поменять элементы темы в одном месте, и изменения будут отражены везде. В обеих темах определяется ряд параметров: фон экрана, меню, логотип, кнопки, цвет текста, отображение таймера (есть в Dashatar, но нет в Simple) и другие. Они находятся в корня репозитория, в директориях dashatar и simple:
/// {@template simple_theme} /// The simple puzzle theme. /// {@endtemplate} class SimpleTheme extends PuzzleTheme { /// {@macro simple_theme} const SimpleTheme() : super(); @override Color get backgroundColor => PuzzleColors.white; @override Color get buttonColor => PuzzleColors.primary6; @override Color get hoverColor => PuzzleColors.primary3; @override Color get pressedColor => PuzzleColors.primary7; ... }
В каждой теме есть LayoutDelegate, с его помощью вычисляется макет. Новые темы можно создавать, повторно используя одни и те же объекты макета. Останется настроить параметры.
Для дизайна сложнее можно настроить всю тему LayoutDelegate. Например, чтобы создать пользовательский фон, отображаемый только на большом экране, можно переопределить backgroundBuilder:
@override Widget backgroundBuilder(PuzzleState state) { return Positioned( bottom: 74, right: 50, child: ResponsiveLayoutBuilder( small: (_, child) => const SizedBox(), medium: (_, child) => const SizedBox(), large: (_, child) => const DashatarThemePicker(), ), ); }
Анимация
Анимация — прекрасный элемент головоломки для изучения. В простой теме Simple нет анимации, зато несколько поэтапных анимаций реализуется в коде Dashatar. Эти анимации управляются одним контроллером, в котором есть Interval для настройки задержки анимации и Tween для определения диапазона значений анимации.
Это можно увидеть в собранной головоломке, в теме Dashatar, где последовательно отображаются несколько виджетов, анимируя смещение блока и непрозрачность. Похожим образом, используя ту же технику, с каждым тиком медленно растёт, а затем исчезает таймер обратного отсчёта, прежде чем появится следующий таймер:

Большинство анимаций в теме Dashatar неявные: нет необходимости писать всю анимацию самостоятельно — изменения свойств анимируются самими виджетами. Например, виджетом DashatarPuzzleTile анимируется перемещение квадратиков по нажатию на них. Благодаря неявно анимированному AnimatedAlign текущее положение квадрата меняется согласно заданному movementDuration:
class DashatarPuzzleTile extends StatelessWidget { ... final Tile tile; @override Widget build(BuildContext context) { return AnimatedAlign( alignment: FractionalOffset( (tile.currentPosition.x - 1) / (size - 1), (tile.currentPosition.y - 1) / (size - 1), ), duration: movementDuration, curve: Curves.easeInOut, child: ResponsiveLayoutBuilder(...), ); } }
Головоломка для веба
При головоломки создан для веба. Для малого, среднего и большого экранов реализован адаптивный дизайн. Кроме того, есть ResponsiveLayoutBuilder с обёрткой вокруг виджета LayoutBuilder на Flutter, позволяющей указывать разные виджеты на разных контрольных точках.
Нужно учесть и дополнительные обстоятельства в вебе. Чтобы оптимизировать производительность во время игры, изображения и аудио предварительно кешируются.
Когда пользователь попадает в игру-головоломку по умолчанию — Simple, файлы для версии Dashatar загружаются в фоновом режиме. Аналогичный подход мы использовали при загрузке всех свойств для I/O Photo Booth (фотобудки ввода-вывода). Так мы гарантируем, что при переходе к теме Dashatar большинство файлов уже загружены.
Можно проявить творческий подход и попробовать сделать головоломку на несколько платформ. Как она будет выглядеть на мобильных устройствах и настольных компьютерах? Как адаптировать идеи для разных платформ?
Доступность
При создании «Пятнашек» учитывалась доступность. Взаимодействие с головоломкой возможно с помощью клавиатуры, для этого есть виджет RawKeyboardListener, который использует обратный вызов, когда пользователь нажимает или отпускает клавишу на клавиатуре.
С приложением можно взаимодействовать через программы чтения с экрана. Это делается с помощью семантических меток. Для некоторых действий есть всплывающие подсказки: используется виджет Tooltip.
Если вы пишете «Пятнашки» с нуля, настоятельно рекомендуем сделать головоломку доступной для всех пользователей (применяйте стратегии, аналогичные описанным выше).
Другие идеи
За основу берите кодовую базу из демо, или воплощайте новую идею с нуля. Важно, чтобы в заявке была рабочая головоломка, но результат зависит только от вас!
Из примеров Simple и Dashatar можно позаимствовать идеи настроек или чего-то интересного, что можно сделать самостоятельно. Одна интересная идея — проецировать на квадратики головоломки созданную Феликсом Блашке Flutter Plasma.
Эффект плазмы достигается применением виджета CustomPaint, обёрнутого в виджет Transform и анимированного с помощью AnimationController. Вот пример отрисовки плазмы из демо:

Ещё одна идея — получать изображения или другие данные от API. Например, чтобы сделать «Пятнашки», можно использовать Google Photos API, взяв фотографии одного из альбомов Google Photos. В этом конкурсе нет предела совершенству!
Посмотрите пример кода головоломки здесь. Поделитесь с нами своими творениями в Twitter с помощью хештега #FlutterPuzzleHack. Ждём с нетерпением!
Лицензия кода — MIT, так что его легко использовать в ваших «Пятнашках». А продолжить погружение в IT и прокачать ваши навыки вы сможете на наших курсах:
Выбрать другую востребованную профессию.

Краткий каталог курсов и профессий
Data Science и Machine Learning
Python, веб-разработка
Мобильная разработка
Java и C#
От основ — в глубину
А также
ссылка на оригинал статьи https://habr.com/ru/company/skillfactory/blog/652845/
Добавить комментарий