Разработка мобильной игры на Flame (Flutter)
Flame — игровой движок поверх Flutter. Не отдельный фреймворк, а пакет, который добавляет game loop, систему компонентов, физику и обработку ввода прямо в Flutter-проект. Это значит: одна кодовая база для игры и для UI вокруг неё (меню, настройки, магазин), нативная работа на iOS, Android, Web и Desktop.
Выбирают Flame когда: команда уже работает на Flutter и Dart, нужна 2D-игра без тяжёлого игрового движка, или игровой контент встраивается в существующее Flutter-приложение.
Архитектура Flame
Flame использует Component/Entity систему. FlameGame — корневой компонент с game loop. Component — базовый класс для всего: спрайты, тексты, коллизии, UI-элементы.
class SpaceGame extends FlameGame {
@override
Future<void> onLoad() async {
add(Player());
add(StarBackground());
add(EnemySpawner());
}
}
HasCollisionDetection mixin добавляет коллизии к игре. ShapeHitbox (Rectangle, Circle, Polygon) — хитбоксы компонентов. Callbacks onCollisionStart, onCollision, onCollisionEnd.
Тики и физика. Flame предоставляет update(double dt) — delta time в секундах. Физика через Forge2D (Box2D-порт для Dart) — отдельный пакет flame_forge2d. Для простых игр встроенная коллизионная система Flame достаточна без Box2D.
Практика: типичный компонент
class Enemy extends SpriteComponent with HasGameRef<SpaceGame>, CollisionCallbacks {
Enemy() : super(size: Vector2(64, 64));
@override
Future<void> onLoad() async {
sprite = await gameRef.loadSprite('enemy.png');
add(RectangleHitbox());
}
@override
void update(double dt) {
super.update(dt);
position.y += 150 * dt; // движение вниз
if (position.y > gameRef.size.y) removeFromParent();
}
@override
void onCollisionStart(Set<Vector2> points, PositionComponent other) {
if (other is Bullet) {
removeFromParent();
gameRef.score.increment();
}
}
}
removeFromParent() — правильный способ удаления. remove() напрямую через gameRef добавляет задержку на один тик.
Производительность в Flame
Flame рендерит через Flutter's Canvas API — это не GPU-инстансинг, а прямые вызовы canvas.drawImageRect. Для большого числа одинаковых спрайтов (100+ частиц, пуль) используем SpriteParticle из пакета flame_particles или собственный CustomPainter с drawAtlas — это батчит рисование в один draw call.
Sprite Sheet. SpriteAnimation из атласа — SpriteSheet.fromColumnsAndRows. Загрузка отдельных PNG на каждый кадр — анти-паттерн. gameRef.images.load() кэширует изображение, повторные вызовы возвращают кэш.
Flame работает поверх Flutter widget tree — это даёт доступ к FlameGame.overlays для встройки Flutter-виджетов (кнопки паузы, счёт, модальные окна) прямо поверх canvas без отдельного слоя.
Ограничения
3D в Flame отсутствует. Сложная физика (ragdoll, joints, чувствительные к физике пазлы) — Forge2D справляется, но Unity Box2D интеграция зрелее. Если проект требует серьёзной 3D-графики — Flame не тот выбор.
Размер сообщества меньше, чем у Unity/Godot — плагинов меньше, Stack Overflow-ответов меньше.
Сроки
Гиперказуальный или казуальный прототип: 3–6 недель. Полноценная 2D-игра с прогрессией, магазином, интеграцией AdMob и IAP: 2–5 месяцев. Стоимость рассчитывается после анализа концепции игры.







