Рубрика: Flutter и Dart

Бесплатные книги и видео-курсы по Flutter и Dart разработке кроссплатформенных приложений

  • Flutter Hero анимация. Видео-курс

    Создавайте впечатляющие анимации героев, используя виджет героя в Flutter при переходе с одного экрана на другой. Этот курс охватывает ключевые темы, такие как основы анимации Hero, использование компонентов виджета Hero для создания продвинутых анимаций и практическая разработка визуально потрясающих анимаций во время работы над приложением Fooder.

    Для кого этот курс?

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

    Рассмотренные концепции

    Dart 2.19, Flutter 3.7, VS Code 1.75

    • Hero Animations
    • Виджет Hero (Hero Widget)
    • Keys во флаттере
    • Создание пользовательских переходов по маршруту с помощью PageRouteBuilder
    • Использование AnimationController для управления анимациями
    • Создание Tween Animations
    • Использование виджета WillPopScope для обработки поведения кнопки «Назад»
    • Использование инструментов разработки Dart для мониторинга анимации
    • Создание пошаговой анимации (staggered animations)

    Смотреть видео-курс

    Скачать материалы и код курса

  • Разработка Flutter Desktop приложений. Видео-курс

    Узнайте, как создать настольное приложение Flutter для платформ Macintosh и Windows. Создавайте приложения, которые работают так же быстро, как и нативные приложения, и выглядят как нативное приложение. Используйте встроенную систему меню и получайте доступ к локальным файлам.

    Для кого этот курс?

    Этот бесплатный курс на русском языке будет полезен разработчикам, заинтересованным в разработке настольных приложений для компьютеров Macintosh и Windows, используя платформу Flutter.

    Рассмотренные концепции

    Dart 2.19, Flutter 3.7, Android Studio 2021.3.1 или выше

    • Пользовательский интерфейс Flutter UI
    • Разработка настольных Desktop приложений
    • Меню рабочего стола (Desktop Menus)
    • Импорт и экспорт данных
    • Сохранение данных в базу данных

    Смотреть видео-курс

    Скачать материалы и код курса

  • Как создать 2D игру Snake на Flutter. Видео-курс

    Узнайте, как создать 2D игру Snake (змейка) в Flutter для платформ Android и iOS. Вы узнаете, как использовать Flutter в качестве простого игрового движка, создав классическую 2D игру со змеями. Вы познакомитесь с основами 2D игровой графики и управления объектами на экране.

    Для кого этот курс?

    Этот бесплатный видео-курс на русском языке предназначен для начинающих разработчиков, которые хотят изучить реализацию графики, движения и игровой логики во Flutter без использования каких-либо сторонних библиотек, чисто Flutter.

    Охватываемые концепции

    Dart 2.17, Flutter 3.0, Android Studio or VS Code

    • Используйте Flutter в качестве движка 2D игры
    • Перемещение объектов
    • Управление движением
    • Создание игрового интерфейса (game UI)
    • Добавить игровые элементы

    Смотреть видео-курс

    Скачать материалы и код курса

  • Мастер-класс по анимации во Flutter. Видео-курс

    Освойте анимацию Flutter и узнайте, как создавать приложения, которые ярко выделяются!

    Содержание курса

    Этот бесплатный курс на русском языке состоит из 10 независимых модулей, каждый из которых имеет определенную цель обучения тонкостям работы с анимацией во Флаттер (Flutter).

    Рассматриваемые темы и концепции

    1. Введение и неявная анимация (Implicit Animations)

    1. План курса и ресурсы
    2. Введение в анимацию
    3. Загрузите проект анимационной игровой площадки
    4. Неявная анимация с помощью AnimatedContainer
    5. [Упражнение] AnimatedOpacity
    6. Кривые анимации
    7. Введение в TweenAnimationBuilder
    8. Анимация цветов HSV с помощью TweenAnimationBuilder
    9. Подведение итогов по неявным анимациям

    2. Проблема пользовательского интерфейса: приложение для секундомера

    1. Введение в модуль
    2. Начальный проект для приложения Секундомер (Stopwatch app)
    3. Темный режим и пользовательское наложение пользовательского интерфейса системы
    4. Создание периодического таймера
    5. Ticker и TickerProvider
    6. Создание отдельного StopwatchRenderer виджета
    7. Настройка пользовательского интерфейса секундомера с помощью AspectRatio
    8. Матричные преобразования
    9. Получение радиуса окружности из LayoutBuilder
    10. Реализация анимированной часовой стрелки
    11. Завершение интерфейса секундомера (часть 1)
    12. Завершение пользовательского интерфейса секундомера (часть 2)
    13. Добавление функций запуска / остановки / сброса (часть 1)
    14. Добавление функций запуска / остановки / сброса (часть 2)
    15. Соображения по производительности и тестированию при работе с тикерами!

    3. Обзор приложения для отслеживания привычек

    1. Приложение для отслеживания привычек: введение (Habit Tracker app)
    2. Загрузите начальный проект
    3. Правила линтинга
    4. Пошаговое руководство по коду: ресурсы проекта
    5. Пошаговое руководство по коду: цвета и тематизация

    4. Явная анимация

    1. Вводный модуль и начальный проект
    2. Кольцо завершения задачи: техническое планирование
    3. Введение в CustomPainter
    4. Рисование кольца завершения задачи с помощью холста
    5. Введение в явную анимацию (Explicit Animations) с AnimationController
    6. Анимированное кольцо завершения задачи с AnimationController и AnimatedBuilder
    7. Управление анимацией с помощью GestureDetector
    8. Добавление значка SVG по центру к анимированной задаче
    9. Настройки пользовательского интерфейса для завершения задачи
    10. Состояние завершения задачи и окончательные настройки
    11. Исправлена ошибка: обработка жестов отмены нажатия
    12. Добавление имени задачи
    13. Организация нескольких задач внутри GridView
    14. Законченный проект и подведение итогов

    5. Сохранение локальных данных с помощью Hive

    1. Введение модуля
    2. Техническое планирование: локальное (Local Data) или удаленное хранилище
    3. Обзор начального проекта
    4. Введение в Hive
    5. Создание классов моделей с помощью Hive
    6. Создание адаптера типов с генерацией кода
    7. Создание HiveDataStore
    8. Создание демонстрационных задач внутри main()
    9. Создание уникальных идентификаторов задач с помощью пакета uuid
    10. Чтение заданий с ValueListenableBuilder
    11. Подведение итогов

    6. Управление состоянием с помощью Riverpod

    1. Вводный модуль и начальный проект
    2. Знакомство с Riverpod
    3. Создание и использование хранилища данных Provider с помощью Consumer
    4. Зависимость переопределяется с помощью ProviderScope
    5. TaskState моделирование данных
    6. Создание и использование TaskState класса модели Hive
    7. Добавление onCompleted обратного вызова к AnimatedTask виджету
    8. Создание TaskWithNameLoader
    9. Завершение + использование инспектора виджетов

    7. Анимация перелистывания страницы

    1. Введение модуля: переход с переворота страницы
    2. Начальный проект и пошаговое руководство
    3. Разработка API-интерфейса виджета Page Flip с помощью WidgetBuilders
    4. Использование a GlobalKey для изменения состояния дочернего виджета
    5. AnimationController настройка
    6. AnimatedBuilder против AnimatedWidget
    7. Код поворота с Transform и Matrix4
    8. Интерактивный переход с одной страницы на другую
    9. Виджеты, элементы и клавиши
    10. Дополнительная задача: игра с переворачиванием карт

    8. Расширенная тематизация

    1. Введение к модулю: Расширенная тематизация (Theming)
    2. Начальный проект и пошаговое руководство
    3. Показ нижних панелей
    4. Создание SlidingPanelAnimator
    5. Использование SlidingPanelAnimator
    6. Анимация раздвижных панелей
    7. Управление изменениями состояния темы приложения: обзор
    8. Реализация класса AppThemeManager с помощью StateNotifier
    9. Создание и использование поставщиков AppThemeManager
    10. Применение настроек AppThemeSettings
    11. Расширенное анимированное тематическое оформление с помощью ImplicitlyAnimatedWidget

    9. Более явная анимация

    1. Вводный модуль
    2. Начальный проект и пошаговое руководство
    3. Управление анимацией в виджете TasksGrid
    4. Добавление подкласса AnimatedWidget для масштабирования виджетов
    5. Пошаговая анимация
    6. Добавление виджета AddTaskItem
    7. Анимация плавного перехода с помощью виджета непрозрачности
    8. Явная анимация с переходом на затухание и масштабированием
    9. Обзор: встроенный переход против неявно анимированных виджетов во Flutter
    10. Исправлена ошибка: отключение завершения задачи в режиме редактирования

    10. Добавление и редактирование задач

    1. Введение в модуль: Добавление и редактирование задач
    2. Переход к страницам добавления задачи и редактирования задачи
    3. Обзор: AddTaskPage с помощью slivers
    4. Обзор: TaskDetailsPage и SelectIconPage
    5. Обзор: адаптация
    6. Заключение и следующие шаги

    Дополнительные ресурсы

    Полезные ресурсы из документации Flutter

    Смотреть видео-курс

    Часть 1:

    Часть 2:

    Часть 3:

    Часть 4:

    Часть 5:

    Часть 6:

    Часть 7:

    Скачать материалы и код курса

  • Создайте прорывную игру на Flutter с помощью Flame и Forge2D – Часть 1

    По мере того, как Flutter продолжает развиваться и расширять свои возможности на нескольких платформах, он также расширяется, охватывая новые области программного обеспечения, такие как разработка игр. В результате все больше инди-разработчиков прыгают на подножку и создают отличные игры с использованием Flutter.

    У вас есть несколько вариантов создания игры во Flutter. Ваш выбор во многом будет зависеть от типа игры, которую вы хотите создать. Например, Филип Грачек создал игру в крестики-нолики, используя только виджеты Flutter, а в курсе «Создание игр в Flutter с Flame: начало работы с Flame» разработана 2D-орфографическая игра.

    Это первая из трех статей мини-курса, в которых показано, как создать версию классической игры Breakout с использованием Flame и Forge2D, движка двумерного физического симулятора для игр.

    Законченный прорывной игровой проект

    Вот что вы узнаете из каждой части:

    • В части 1 вы изучите основы создания игры Forge2D с использованием Flutter и Flame. Затем вы узнаете, как настроить игровой цикл и создавать твердые тела в моделируемом двумерном физическом мире. К концу статьи вы создадите игру Forge2D с мячом, который рикошетит от стен замкнутого пространства.
    • В части 2 вы продолжите создавать оставшиеся компоненты для своей Прорывной игры. Вы узнаете, как построить кирпичную стену и управляемую пользователем лопатку. К концу статьи у вас будут все необходимые элементы для вашей Прорывной игры.
    • И, наконец, в части 3 вы узнаете, как добавить логику геймплея и дополнить свою игру визуальным оформлением, завершив внешний вид играбельной прорывной игры.

    В этом руководстве предполагается, что вы использовали Flutter и знаете, как создать и запустить проект Flutter. Хотя это и не является обязательным требованием, вы должны иметь базовое представление о трех законах Ньютона о движениивекторах и Пламени. Если вы не знакомы с Flame, статья о создании игр в Flutter with Flame: начало работы — отличное введение.

    Приступая к работе

    Создание прорывной игры в Forge2D — достаточно сложная задача, поэтому имеет смысл разбить ее на три части. В первой части вашего путешествия вы узнаете, как:

    • Создайте Flame GameWidgetс Forge2DGame дочерним виджетом.
    • Создавайте тела и приспособления, составляющие строительные блоки мира Forge2D.
    • Поработайте с мировыми координатами Forge2D и узнайте, как они соотносятся с логическими пикселями Flutter.
    • Узнайте больше о Flame Cameraи просмотре в мире Forge2D.

    Для завершения этого урока вам понадобится начальный проект. Загрузите его (материал урока в конце статьи).

    Откройте проект в предпочитаемой вами среде разработки. В этом руководстве использовался код Visual Studio, но должна работать любая среда разработки Flutter. Затем откройте pubspec.yaml и получите зависимости проекта, затем создайте и запустите проект.

    Вы увидите зеленую рамку и надпись «Игровой мир пламени» Здесь! по центру дисплея.

    Начальный экран приложения

    Изображения экрана в этом руководстве взяты из симулятора iOS, но приложение будет работать и выглядеть аналогично на Android или в браузере Chrome.

    Найдите минутку, чтобы ознакомиться с начальным проектом. Этот проект представляет собой минимальное приложение Flutter с простой реализацией lib / main.dart, которая создает экземпляр MainGamePage виджета. Посмотрите на MainGameState класс widget в lib/ui/main_game_page.dart, и вы увидите Scaffold виджет с Container виджетом для тела. В этом уроке вы замените Container дочерний виджет, Center виджет, на Flame GameWidget. Он GameWidget будет содержать мир Forge2D вашей прорывной игры.

    Требования к прорывной игре

    Цель игры проста — уничтожить все кирпичи в стене, многократно отбивая мяч от весла. Каждый раз, когда мяч попадает в кирпич, этот кирпич разрушается. Уничтожьте все кирпичи, и вы выиграете игру. Пропустите мяч, и вы проиграете игру.

    Прорыв состоит из трех компонентов:

    • Мяч в движении.
    • Управляемая пользователем лопатка.
    • Стена из кирпичей.

    Чтобы создать игру, вам нужно нарисовать мяч на экране и изменить его положение таким образом, чтобы имитировать движение мяча в реальном мире. Затем вам нужно будет определить, когда мяч соприкасается с кирпичом, ракеткой или стенками игровой площадки, а затем заставить мяч отскакивать от них, как мяч в реальном мире. Игроки ожидают, что поведение мяча при прорыве будет имитировать реальные примеры, такие как теннис или гандбол. В противном случае его поведение было бы запутанным или неожиданным для игрока.

    Хотя вы можете создать прорывную игру, используя только Дротик и Пламя, вам придется выполнить все вычисления для физического взаимодействия между мячом, ракеткой и кирпичами. Это большая работа! И здесь на помощь приходит Forge2D.

    Понимание игрового движка Flame и Forge2D

    Forge2D — это двумерный физический симулятор, специально разработанный для игр. Forge2D интегрируется с игровым движком Flame для работы с игровым циклом Flame для обновления и визуализации объектов, подчиняясь трем законам движения Ньютона. Итак, вы можете создать мяч, весло и стену из кирпичей в Forge2D, а затем позволить ему выполнять всю тяжелую работу.

    Добавление зависимостей Flame и Forge2D

    Начните с открытия файла pubspec.yaml в вашем проекте и добавьте пакеты flame и flame_forge2D:

    dependencies:
      flame: ^1.4.0
      flame_forge2d: ^0.12.3
      flutter:
        sdk: flutter
    

    Сохраните файл pubspec.yaml и запустите flutter pub get, чтобы получить пакеты.

    Настройка игрового цикла Flame

    Первый шаг в создании вашей игры — создать игровой цикл Flame. Игровой цикл — это основной компонент, пульсирующее сердце вашей игры. Отсюда вы будете создавать все свои игровые компоненты и управлять ими.

    Откройте папку библиотеки и создайте файл с именем forge2d_game_world.dart. Затем добавьте новый класс с именем Forge2dGameWorld в этот файл. Ваша игра расширит базовый игровой виджет Forge2DForge2DGame:

    import 'package:flame_forge2d/flame_forge2d.dart';
    
    class Forge2dGameWorld extends Forge2DGame {
      @override
      Future<void> onLoad() async {
        // empty
      }
    }

    Типичная игра Flame расширяет FlameGame класс, чтобы получить цикл игры Flame и другие основные свойства и поведение Flame. Аналогично расширяется и игра Forge2DGameForge2D . Forge2DGame расширяется FlameGame, чтобы предоставлять функции Forge2D в дополнение FlameGameк функциям вашей игры.

    Затем откройте main_game_page.dart и добавьте эти два импорта с помощью инструкции other import в верхней части файла:

    import 'package:flame/game.dart';
    import '../forge2d_game_world.dart';
    

    Затем в том же файле создайте экземпляр вашего нового класса игрового цикла, заменив комментарий // TODO: Create instance of Forge2dGameWorld here.

      final forge2dGameWorld = Forge2dGameWorld();
    

    Документация Flame рекомендует создавать экземпляр игры вне метода сборки. Создание экземпляра вашей игры в build методе приведет к тому, что ваша игра будет перестраиваться каждый раз, когда дерево Флаттера будет перестроено, что обычно происходит чаще, чем вам хотелось бы.

    Теперь замените Centerвиджет под комментарием // TODO: Replace Center widget with GameWidgetна a GameWidgetи ваш forge2dGameWorldэкземпляр:

      child: GameWidget(
        game: forge2dGameWorld,
      ),
    

    Создайте и запустите свой проект. Теперь вы увидите знакомую зеленую рамку вокруг черного прямоугольника, но текст исчез. TextВиджет по центру был заменен вашим FlameGameWidget, ожидающим добавления игровых компонентов.

    Empty Game World

    Создание шара

    FlameGame, и, как следствие, Forge2DGame, — это игровая платформа, основанная на компонентах. Он управляет деревом компонентов, аналогично тому, как Flutter управляет деревом виджетов. Игровой цикл неоднократно вызывает методы update и render компонентов, которые вы добавляете в свою игру, позволяя вам взаимодействовать с компонентами и добавлять игровую логику.

    Чтобы создать шар, вам нужно описать физические свойства шара как твердого тела для Forge2D и обернуть его в компонент, которым будет управлять Flame. Вы предоставите это описание , объявив Ball класс , который расширяется от a BodyComponent.

    Определение физических свойств шара

    Тела — это фундаментальные объекты в физике. Они обладают физическими свойствами твердого тела. В Forge2D существует три типа тел: статические, динамические и кинематические:

    • Неподвижные тела не двигаются. Кирпичи в кирпичной стене будут статичными телами.
    • Динамические тела реагируют на силы. Forge2D обновляет динамические тела, подчиняясь законам движения Ньютона. Мяч и лопатка являются динамическими телами.
    • Кинематические тела представляют собой гибрид статических и динамических тел. Колесо обозрения — это пример кинематического тела. Положение колеса обозрения остается фиксированным, но движение колеса обозрения, вращающегося вокруг своего центра, является динамичным. В игре Breakout не используются кинематические тела.

    Приспособления имеют форму тела. Forge2D использует приспособления для определения столкновений между телами. Тела могут иметь ноль или более креплений. Тело без приспособлений относительно бессмысленно, поскольку приспособления придают телу физическое присутствие в мире Forge2D. Приспособления имеют форму и плотность, обеспечивая, таким образом, массу корпуса. Например, мяч в вашей игре будет иметь единственное приспособление круглой формы. Так зачем же телу иметь несколько приспособлений? Рассмотрим вентилятор с четырьмя лопастями. Корпус вентилятора должен иметь четыре крепления, имеющие форму многоугольника для каждой лопасти вентилятора, расположенной с интервалом в 90 градусов вокруг центра корпуса.

    Создайте новую папку с именем components в папке lib. В этой папке вы будете хранить файлы своих игровых компонентов. Затем создайте файл ball.dart в этой папке и добавьте в этот файл следующие строки кода:

    import ;
    
    import '../forge2d_game_world.dart';
    
    // 1
    class  Ballextends BodyComponent<Forge2dGameWorld> {
     // 2
      final Vector2 position;
     final double radius;
    
     Ball({required this.position, required this.radius});
    
     // 3
      @override
     Body createBody() {
     // 4
        final bodyDef = BodyDef()
     ..type = BodyType.dynamic
     ..position = position;
    
     // 5
        final ball = world.createBody(bodyDef);
    
     // 6
        final shape = CircleShape()..radius = radius;
    
     // 7
        final fixtureDef = FixtureDef(shape);
    
     // 8
     ball.createFixture(fixtureDef);
     return ball;
     }
    }
    

    Проходя через это шаг за шагом:

    1. Вы начинаете с того, что объявляете себя BallBodyComponent, твердым телом в Forge2D и компонентом для Flame. Затем укажите Forge2dGameWorld в качестве BodyComponentтипа игрового мира. Эта ассоциация дает вашему классу ball доступ к общедоступным свойствам вашего игрового мира.
    2. Когда вы создаете свой шар, вы указываете его начальное положение и размер.
    3. Вы рассказываете Forge2D , как создать свое тело внутри createBody. Forge2D вызываетсяcreateBody, когда вы добавляете тело в игровой мир.
    4. Определите базовые свойства тела шара. Мяч свободно перемещается по миру, поэтому его тип динамический. Позиция будет передана в конструктор при добавлении шара в мир; это позволяет вам установить начальную позицию шара.
    5. Используйте определение тела, чтобы создать твердое тело в вашем игровом мире. world является наследуемым свойством от BodyComponentвашего Forge2dGameWorld экземпляра.
    6. Если Body«а» — это душа твердого тела, Fixtureто «с» — это его кожа и кости. Чтобы определить приспособление, вы начинаете с определения формы. В этом случае ваш шар будет иметь форму круга в этом 2D-мире.
    7. Используя форму, вы создаете определение приспособления.
    8. Используйте метод шара createFixture, чтобы создать и добавить приспособление к корпусу шара.

    Затем создайте шар и добавьте его в свой Forge2D world, открыв файл forge2d_game_world.dart и создание частного метода с именем _initializeGame. Теперь вызовите процедуру onLoadпримерно так:

    import 'package:flame_forge2d/flame_forge2d.dart';
    
    import 'components/ball.dart';
    
    class Forge2dGameWorld extends Forge2DGame {
      @override
      Future<void> onLoad() async {
        await _initializeGame();
      }
    
      Future<void> _initializeGame() async {
        final ball = Ball(
          radius: 1.0,
          position: size / 2,
        );
        await add(ball);
      }
    }
    

    Дайте мячу radius значение 1.0 и начните position с центра игровой зоны. size предоставляет вам размер видимой игровой области в Forge2dGameWorld. Грядет обсуждение модулей Forge2D, координат, видовых экранов и камеры. Итак, пока используйте эти значения с пониманием того, что вскоре вы получите объяснение.

    Создайте и запустите свой проект, и вы увидите маленький белый кружок, представляющий ваш мяч, падающий с нижней части экрана.

    Тело шара падает в нижнюю часть экрана

    Что происходит? Куда делся мяч? Мяч все еще там, в вашем мире Forge2D. Это просто навсегда проваливается в огромную темную пустоту за нижней частью экрана, очень похоже на то, как «Вояджер-1» и «Вояджер-2» несутся в космосе.

    Мяч, падающий с экрана, не очень веселый. Итак, далее вы узнаете, как строить стены, чтобы удерживать мяч в игровой зоне.

    Создание игровой арены

    Игровой мир Forge2D больше похож на огромное пустое пространство, чем на мир. Вы создаете тела и другие компоненты своего мира, чтобы заполнить пространство.

    Пользователь играет в Breakout в закрытом помещении, например на арене. Теперь вы создадите арену, чтобы удерживать мяч в определенной области вашего мира. Создайте файл arena.dart в папке components и добавьте в этот файл следующие строки кода:

    import ;
    
    import '../forge2d_game_world.dart';
    
    // 1
    class  Arenaextends BodyComponent<Forge2dGameWorld> {
     Vector2? size;
    
     // 2
     Arena({this.size}) {
     assert(size == null || size!.x >= 1.0 && size!.y >= 1.0);
     }
    
     late Vector2 arenaSize;
    
     // 3
      @override
     Future<void> onLoad() {
     arenaSize = size ?? gameRef.size;
     return super.onLoad();
     }
    
     // 4
      @override
     Body createBody() {
     final bodyDef = BodyDef()
     ..position = Vector2(0, 0)
     ..type = BodyType.static;
    
     final arenaBody = world.createBody(bodyDef);
    
     // 5
        final vertices = <Vector2>[
     arenaSize,
     Vector2(0, arenaSize.y),
     Vector2(0, 0),
     Vector2(arenaSize.x, 0),
    ];
    
     // 6
        final chain = ChainShape()..createLoop(vertices);
    
     // 7
        for (var index = 0; index < chain.childCount; index++) {
     arenaBody.createFixture(FixtureDef(chain.childEdge(index)));
     }
    
     return arenaBody;
     }
    }

    Арена содержит многие из тех же элементов, которые вы изучили при создании корпуса мяча. Может быть полезно шаг за шагом обсудить, что осталось прежним, а что новым:

    1. Арена — это еще один компонент тела в вашем игровом мире. Он действует как забор, ограждающий объекты в вашей игре.
    2. ArenaКонструктор имеет необязательный sizeпараметр для определения протяженности прямоугольной арены. Оставьте это поле пустым; onLoadметод установит размер, чтобы заполнить доступное пространство виджета.
    3. onLoad это BodyComponentметод состояния. onLoad вызывается перед createBodyтем, как разрешить любую инициализацию, которую вам может потребоваться выполнить. Здесь вы получаете размер видимой области в мировых координатах Forge2D. Подробнее о мировых координатах вы узнаете в следующем разделе.
    4. Вы уже видели этот метод раньше. Вот где вы строите свое тело на арене. Установка positionна мировое происхождение выравнивает арену с верхним левым угломGameWidget. Поскольку стены арены не двигаются, тип корпуса арены статичен.
    5. Создав тело арены, теперь вам нужно определить ее приспособления. Приспособлениями арены будут стены, которые окружают территорию. Forge2D имеет ChainShapeпроизвольную последовательность линейных сегментов, идеально подходящую для ограждения арены. Итак, сначала вы создаете список местоположений четырех углов арены.
    6. Затем создайте a ChainShapeиз списка вершин. Этот createLoop метод автоматически замыкает цикл для вас.
    7. Теперь создайте приспособления для каждого края цепочки. ChainShape предоставляет отличный метод, который возвращает EdgeShapeзначение для каждого сегмента в цепочке для использования при создании приспособлений арены. Это стены вашей арены.

    Теперь вам нужно создать экземпляр арены и добавить его в свой мир Forge2D. Откройте файл forge2d_game_world.dart, добавьте импорт для arena.dart и создайте экземпляр Arenain _initializeGame выше, где вы создаете экземплярBall:

    import 'components/arena.dart';
    
      Future<void> _initializeGame() async {
        final arena = Arena();
        await add(arena);

    Создайте и запустите свой проект. Белый круг теперь опускается и останавливается у нижнего края GameWidget области. Поздравляю! Вы завладели мячом и продвинулись далеко на пути к созданию своей Прорывной игры.

    Мяч Ограничен на Арене

    Понимание единиц и координат Forge2D

    Вы создали a GameWidgetв Flutter, добавили a Forge2dGameWorld и создали два жестких тела: динамический шар и статическую арену. При этом вы использовали значения радиуса и положения мяча, а также расположение стен арены. Итак, каков контекст для этих единиц измерения и координат?

    Мир Forge2D более или менее бесконечен или, по крайней мере, настолько безграничен, насколько может быть смоделированный 2D-мир. Эта обширность объясняется тем, что вы указываете большинство единиц измерения в Forge2D, используя double тип данных, который может представлять широкий диапазон значений. Но что означают эти значения единиц измерения?

    Единицы измерения

    Эрин Катто, создатель Box2D — прямого предка Forge2D — написала Box2D для настройки на мир единиц измерения MKS (метров / килограммов / секунд). Эта настройка устройства также присуща Forge2D. Катто написал в документации Box2D:

    «… заманчиво использовать пиксели в качестве единиц измерения. К сожалению, это приведет к плохой симуляции и, возможно, к странному поведению. Объект длиной 200 пикселей будет восприниматься Box2D как объект размером с 45-этажное здание «.

    45-этажное здание? Как это так? Что ж, длина 200,0 в Forge2D составляет, по сути, 200 метров. Итак, этаж здания составляет примерно 4,4 метра или 14 футов; 200, разделенные на 4,4, составляют 45,4545, таким образом, 45-этажное здание.

    Компания Catto рекомендует сохранять размер движущихся объектов в пределах от 0,1 до 10 метров, примерно от размера банки из-под супа до школьного автобуса. Он также рекомендует сохранить размер мира менее 2 километров.

    Остальные единицы измерения, используемые в Forge2D, — это углы, измеряемые в радианах, а не градусах; масса, измеряемая в килограммах, и время, измеряемое в секундах.

    Системы координат

    Игровой мир Forge2D использует типичную двумерную декартову систему координат. Вы узнали, что, хотя единицы измерения длины явно не определены, вы должны думать о них в терминах метров. Длины, силы, расстояния и положения определяются двумерными векторами значений измерителя. Например, вектор Vector2(2,3)простирается на два метра в направлении x и на три метра в направлении y в Forge2D.

    2D декартова система координат

    Flutter также использует двумерную декартову систему координат, но ее единицами измерения являются не зависящие от устройства пиксели с перевернутой осью y.

    Координаты 2D экрана

    Итак, что это значит для вашей прорывной игры? Во-первых, вы должны помнить об использовании не зависящих от устройства пикселей при задании значений размера, положения и смещения виджетам Flutter и метрам при задании аналогичных значений компонентам Forge2D. Во-вторых, при переходе между двумя пространствами координат вам необходимо выполнить преобразование между координатами экрана, которые являются независимыми от устройства пикселями Flutter, и мировыми координатами, которые являются метрическими единицами Forge2D.

    Flame и Forge2D предоставляют инструменты, которые помогут вам с этими переводами. Например, flame_forge2d пакет инвертирует значения мировой оси y Forge2D для выравнивания с координатами экрана. Кроме того, существует несколько методов преобразования позиций между экраном и миром Forge2D.

    Камера с пламенем

    Когда вы вглядываетесь в мир Forge2D через GameWidget, вы смотрите через объектив камерыCamera Преобразует систему координат Forge2D в размер вашего экрана. Forge2DGame обеспечивает вашу игру разумной камерой по умолчанию. Перевода нет, поэтому положение камеры устанавливается в исходное положение мира Forge2D. Масштаб камеры равен 10,0. Помните рекомендацию Catto не использовать пиксельные единицы измерения для вашего мира Forge2D? Увеличение камеры эффективно делает 10 независимых от устройства пикселей равными одному метру. Например, GameWidget изображение размером 330 на 760 пикселей, типичный размер экрана, означает, что видимый мир Forge2D составляет 33,0 на 76,0 метров.

    Показатели прорывной игры

    Если посмотреть на настройки, используемые в вашей игре Breakout, у вас есть мяч размером 2,0 метра (радиус 1,0), движущийся по арене размером примерно 33,0 на 76,0 метров на большинстве мобильных устройств. Или, в английских единицах измерения, 6,5-футовый мяч на арене размером 36,0 на 81,1 ярда. Браузер Chrome будет иметь более изменяемый размер арены. Это большой мяч на большой арене.

    Почему это имеет значение? Скорость. Мяч в игре на прорыв движется быстро, преодолевая игровое поле за 1-2 секунды или меньше. Это означает, что мяч движется со скоростью 160 км / ч (100 м / ч) или более. Фух!

    Точная настройка параметров тел в мире Forge2D — это немного интуиции, смешанной с некоторыми экспериментами. В остальных разделах вы будете использовать параметры, которые создают воспроизводимую игру, но не стесняйтесь экспериментировать и пробовать свои значения.

    Настройка свойств камеры, арены и корпуса мяча

    Применяя свои новообретенные знания к своей игре Breakout, вы сначала отрегулируете размер мира Forge2D, который занимает ваша игра Breakout. Добавьте следующий конструктор в верхней части Forge2dGameWorldв forge2d_game_world.dart:

      Forge2dGameWorld() : super(gravity: Vector2.zero(), zoom: 20);
    

    Гравитационная сила по умолчанию Vector2(0.0, 10.0)равна; вот почему мяч падает в нижнюю часть экрана. Помните, что flame_forge2d инвертирует ось y для выравнивания с экраном. Breakout не нуждается в гравитации, поэтому установка gravityна Vector2.zero() выключает его, как парение в космосе.

    Установка zoomпараметра вдвое уменьшает размер мира по сравнению с предыдущим значением, приравнивая 20 независимых от устройства пикселей экрана к одному метру. В результате экран размером 330 на 760 пикселей теперь представляет собой арену размером 18,0 на 40,5 ярда.

    Запустите свой проект прямо сейчас, и вы увидите, что шар увеличился в размере вдвое и остается неподвижным в центре GameWidget экрана.

    Скорректированная гравитация и масштабирование

    Это не очень интересно. Итак, далее вы настроите свойства арены и мяча. Откройте арену. бросьте дротик и измените FixtureDefего, чтобы добавить стенам арены свойства плотноститрения и восстановления.

        for (var index = 0; index < chain.childCount; index++) {
          arenaBody.createFixture(
            FixtureDef(chain.childEdge(index))
              ..density = 2000.0
              ..friction = 0.0
              ..restitution = 0.4,
          );
        }
    

    Плотность 2000 кг / м ^ 2 представляет собой прочную бетонную стену. Кроме того, поверхность не подвержена трению, поэтому мяч не теряет момент при соприкосновении со стенкой. Наконец, дайте стене некоторую упругую отдачу со значением восстановления 40%.

    Теперь отрегулируйте свойства шара. Откройте ball.dart и измените FixtureDef, чтобы добавить восстановление и плотность к шару:

        final fixtureDef = FixtureDef(shape)
          ..restitution = 1.0
          ..density = 1.0;
    

    Возврат 100% — это очень прыгучий мяч. Плотность 1 кг / м ^ 2 приемлема для шара.

    Чтобы завершить настройку, откройте forge2d_game_world.dart. Поскольку в мире теперь нет гравитации, вам нужно приложить силу к шару, чтобы привести его в движение. Внесите следующие изменения в свою игру Forge2D:

    class Forge2dGameWorld extends Forge2DGame {
      Forge2dGameWorld() : super(gravity: Vector2.zero(), zoom: 20);
    
      // 1
      late final Ball _ball;
    
      @override
      Future<void> onLoad() async {
        await _initializeGame();
    
        // 2
        _ball.body.applyLinearImpulse(Vector2(-10, -10));
      }
    
      Future<void> _initializeGame() async {
        final arena = Arena();
        await add(arena);
        // 3
        _ball = Ball(
          
          radius: 0.5,
          position: size / 2,
        );
        await add(_ball);
      }
    }

    В этом коде вы:

    1. Создайте ссылку на закрытую переменную для шара.
    2. Приложите силу к шару после того, как Forge2D завершит создание шара и добавит его в мир.
    3. Используйте _ballпеременную уровня класса и отрегулируйте размер шара так, чтобы он имел радиус 0,5.

    Создайте и запустите свой проект. Мяч теперь рикошетит от стен арены в этом GameWidgetрайоне. Поздравляю! Вы сделали еще один важный шаг к созданию своей прорывной игры.

    Мяч, подпрыгивающий на арене

    Куда идти дальше?

    Вы можете загрузить готовые файлы проекта в нижней части руководства.

    На этом заканчивается часть 1 этого руководства. Здесь вы узнали, как:

    • Создайте Flame GameWidget с Forge2DGame дочерним элементом в приложении Flutter.
    • Создайте и добавьте BodyComponents, описывающие твердые тела в моделируемом 2D-мире Forge2D.
    • Используйте игровой цикл Flame для инициализации игры.
    • Определите физические свойства твердых тел в Forge2D.

    Помните, что если вы хотите узнать больше о движке Flame и Forge2d, вы всегда можете ознакомиться с их документацией здесь и здесь соответственно. Кроме того, как упоминалось ранее, вы можете прочитать наше руководство по созданию игр с помощью Flutter здесь, чтобы получить больше удовольствия от создания игр.

    В частях 2 и 3 руководства по созданию прорывной игры с помощью Flame и Forge2D вы узнаете, как создать оставшиеся компоненты для прорывной игры, добавить логику игрового процесса и создать визуальный скин для своей игры.

    Скачать материал урока

  • Программируем на Dart (Классы). Видео-курс

    В этом заключительном курсе из серии «Программирование с помощью Dart» вы познакомитесь с одним из самых важных аспектов языка: классами. Вы узнаете, как определять свои собственные классы и как использовать объектно-ориентированные функции в языке программирования Dart.

    Для кого этот курс?

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

    Прежде чем начать, вы должны были посмотреть «Программируем на Dart: Основы», «Программирование в Dart: Поток управления и коллекции» и «Программируем на Dart: Функции и замыкания». Этот курс будет основываться на этих основополагающих концепциях и расширит ваше понимание языка программирования Dart.

    Охватываемые концепции

    Dart 2.17, Flutter 3.0, DartPad

    • Классы (Classes)
    • Конструкторы (Constructors)
    • Списки инициализации (Initilization lists)
    • Несколько конструкторов (Multiple constructors)
    • Статические элементы (Static members)
    • Перечисления (Enumerations)
    • Наследование и переопределение (Inheritance & overriding)
    • Абстрактные классы (Abstract classes)
    • Интерфейсы (Interfaces)
    • Миксины (Mixins)
    • Универсальные классы (Generic classes)

    Смотреть видео-курс

    Часть 1:

    Часть 2:

    Скачать материалы и код курса

  • Программируем на Dart (Функции и замыкания). Видео-курс

    Вы продолжите использовать уроки из серии «Программируем на Dart», изучая, как писать функции для максимального повторного использования кода, а также фильтровать и сопоставлять коллекции. Вы также познакомитесь с автономными функциями, называемыми замыканиями, чтобы вывести ваш код Dart на новый уровень.

    Для кого этот курс?

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

    Прежде чем начать, вы должны были посмотреть «Программируем на Dart: Основы» и «Программирование в Dart: Поток управления и коллекции». Этот курс будет основываться на этих основополагающих концепциях и расширит ваше понимание языка программирования Dart.

    Охватываемые концепции

    Dart 2.16, Flutter, DartPad

    • Функции (Functions)
    • Необязательные и именованные параметры (Optional & named parameters)
    • Функциональные переменные (Function variables)
    • Функции псевдонимов (Alias functions)
    • Стрелочная нотация (Arrow notation)
    • Анонимные функции (Anonymous functions)
    • Замыкания (Closures)
    • Дженерики (Generics)

    Смотреть видео-курс

    Часть 1:

    Часть 2:

    Скачать материалы и код курса

  • Программируем на Dart (Control Flow и Коллекции). Видео-курс

    Этот курс будет основан на предыдущем курсе «Программируем на Dart (Основы языка)», в котором вы узнаете, как управлять потоком управления в ваших программах, а также изучите несколько встроенных типов коллекций.

    Для кого этот курс?

    Этот бесплатный видео-курс на русском языке написан для людей, начинающих программирование! Если вы не знаете разницы между циклом или переключателем, то вы обратились по адресу!

    Прежде чем начать, вы должны были посмотреть «Программируем на Dart (Основы языка)». Этот курс будет основываться на этих основополагающих концепциях и расширит ваше понимание языка программирования Dart.

    Охватываемые концепции

    • Циклы While (While Loops)
    • Циклы For (For Loops)
    • Циклы For In (For In Loops)
    • Повторение (Iterating)
    • Оператор переключения (Switch Statement)
    • Карты (Maps)
    • Множества (Sets)

    Смотреть видео-курс

    Часть 1:

    Часть 2:

    Скачать материалы и код курса

  • Программируем на Dart (Основы языка). Видео-курс

    Изучите основные строительные блоки языка программирования Google с открытым исходным кодом Dart, языка разработки Flutter. Этот курс научит вас основам Dart — от логических операторов до управления потоком.

    Для кого это курс?

    Этот бесплатный видео-курс на русском языке написан для людей, начинающих программирование! Если вы не знаете разницы между циклом или переключателем, то вы обратились по адресу!

    Этот курс научит вас основам Dart с нуля, а также рассмотрит основные концепции программирования в целом.

    Прежде чем начать, вы должны были посмотреть свое первое приложение Flutter или, по крайней мере, иметь некоторые базовые знания о Dart. То есть, как создавать переменные и операторы if.

    Охватываемые концепции

    • Комментарии (Comments)
    • Операторы (Operators)
    • Установка условных значений (Set Conditional Values)
    • Списки (Lists)
    • Нулевая Безопасность (Null Safety)

    Смотреть видео-курс

    Скачать материалы и код курса

  • Типы и операции (MDFD0103)

    Жизнь полна разнообразия, и это разнообразие выражается по-разному. Какой зубной пастой вы пользуетесь? Мята? Корица? Какая у вас группа крови? A? B? O+? Какой вид мороженого вы любите? Ванильный? Клубничный? Завиток с пралине и ореховой помадкой? Наличие названий для всех этих разных вещей помогает вам разумно говорить о них. Это также помогает вам распознать, когда что-то не на своем месте. В конце концов, никто не чистит зубы пралине с орехово-ореховой помадкой swirl. Хотя звучит это довольно мило.

    Программные типы так же полезны, как и реальные типы. Они помогают вам классифицировать все различные типы данных, которые вы используете в своем коде.

    В главе 2 “Выражения, переменные и константы” вы узнали, как называть данные с помощью переменных, а также получили краткое введение в типы данных Dart. В этой главе вы узнаете еще больше о типах и о том, что с ними можно делать.

    Типы данных в Dart

    В Dart тип — это способ сообщить компилятору, как вы планируете использовать некоторые данные. К этому моменту в этой книге вы уже видели следующие типы: