Neste post
  1. O critério, aplicado
  2. Onde widget puro ganha, e ganha fácil
  3. Onde Flame ganha, e ganha muito
  4. O modelo mental que funciona
  5. Quando nem Flame basta
  6. O erro que a gente cometeu
  7. Resumo

Toda discussão sobre jogo em Flutter degenera na mesma pergunta binária: usa Flame ou não usa?

A pergunta binária é ruim porque a resposta depende de uma característica do jogo que quase nunca é nomeada. Depois de cinco jogos publicados, o critério que usamos cabe numa linha:

O estado do jogo muda por frame ou muda por evento?

Tudo mais decorre disso.

O critério, aplicado

Um jogo que muda por evento tem estado estável entre interações. Nada acontece até alguém tocar na tela. É o caso de puzzle, cartas, merge, turno e da maior parte dos jogos idle.

Um jogo que muda por frame tem simulação rodando o tempo todo: posição, velocidade, colisão. Ele continua acontecendo mesmo com o dedo parado.

JogoMuda porEscolha
Endless flyer com obstáculosframeFlame
Merge com renda passivaeventowidget puro
Coleção de minijogos curtosevento, na maioriawidget puro
Platformer com física e fasesframe, pesadomotor completo

Note que "por evento" não quer dizer parado. Um idle acumula recurso com o tempo — mas isso é uma função do relógio, calculada quando a tela precisa mostrar, não uma simulação a 60 quadros por segundo.

A diferença não é o jogo "ter movimento". É se o movimento precisa ser simulado passo a passo ou pode ser interpolado entre dois estados. Animação de transição é interpolação, e o Flutter faz isso sozinho.

Onde widget puro ganha, e ganha fácil

Para jogo por evento, usar Flame é adicionar um sistema paralelo sem necessidade.

O que se ganha ficando no Flutter:

Layout responsivo de graça. Grade que se adapta a tela de qualquer tamanho é o problema que o Flutter resolve melhor que qualquer coisa. Reimplementar isso dentro de um canvas é trabalho puro.

Acessibilidade e entrada. Toque, arrastar, foco, leitor de tela — tudo já funciona. Dentro de um canvas, nada disso existe até você construir.

Um sistema só. Menu, loja, configurações e o jogo compartilham widgets, tema e navegação. Sem ponte entre dois mundos.

Ferramentas. Hot reload de verdade, inspetor de widget, tudo o que já existe.

O Mewtopia Merge é o exemplo mais claro disso na nossa lista: grade 5×6 com slots que destravam por nível, merge por arrastar e soltar, renda passiva exponencial e ganho offline com teto. Nada aí é simulação por frame. É estado, regra e transição — e a interface é uma grade responsiva, que é a especialidade da casa.

Onde Flame ganha, e ganha muito

Quando o estado muda por frame, escrever à mão significa reimplementar quatro coisas:

  1. 1. Laço de jogo com delta de tempo. Um AnimationController dá o gatilho por

frame, mas você ainda precisa de um modelo de atualização com tempo decorrido, senão a velocidade muda conforme o aparelho.

  1. 2. Árvore de componentes com ciclo de vida. Objetos que nascem, atualizam,

colidem e morrem. Sem estrutura, isso vira uma lista com condicionais.

  1. 3. Detecção de colisão. É o item que mais parece simples e mais consome

tempo. Colisão contínua com muitos objetos não é um if de retângulo.

  1. 4. Câmera e coordenadas do mundo. Separar sistema de coordenadas do mundo do

sistema de coordenadas da tela é o que permite câmera, zoom e paralaxe.

Fazer os quatro à mão é escrever Flame com menos horas de teste.

O Chihuahua Fly cai nesse lado: voo contínuo, obstáculos que se aproximam, chefes, colisão o tempo todo. Não há versão razoável disso em widget puro.

O modelo mental que funciona

A confusão vem de tratar Flame como alternativa ao Flutter. Ele não é — GameWidget é um widget.

MaterialApp
 ├─ MenuPage        (Flutter normal)
 ├─ LojaPage        (Flutter normal)
 └─ PartidaPage
     └─ GameWidget  (Flame comeca aqui)
         └─ HUD     (pode voltar a ser Flutter por cima)

Isso resolve a falsa escolha. Você não decide para o aplicativo inteiro; decide para a tela de partida. Menu, configuração, loja e ranking continuam sendo Flutter em qualquer cenário — e são a maior parte das telas.

Quando nem Flame basta

Existe um terceiro degrau, e ele é sobre ferramenta, não sobre desenho.

Quando o jogo precisa de física com corpos e materiais, tilemap, editor de cena e um fluxo de criação de fases feito por quem não programa, a conversa muda. Aí o que falta não é uma biblioteca de renderização: é um ambiente de autoria.

Foi por isso que um dos nossos jogos foi construído fora do Flutter — assunto que rende post próprio.

O critério aqui também é curto:

Alguém vai desenhar fases neste jogo?

Se sim, você precisa de editor. Fase escrita em código é sustentável até a terceira; da décima em diante é sofrimento.

O erro que a gente cometeu

Vale registrar, porque é o mais comum: começar com Flame por precaução.

O raciocínio parece prudente — "e se depois precisar de movimento?". Na prática, o custo aparece antes do benefício: você entra num sistema de coordenadas próprio, perde layout responsivo, e reimplementa botão e lista dentro do canvas para uma necessidade que talvez nunca chegue.

O caminho barato é o contrário. Comece em widget e mova para Flame a tela de partida, se ela precisar. A migração é local, porque só aquela tela muda.

Resumo

  • A pergunta é se o estado muda por frame ou por evento. Todo o resto decorre.
  • Por evento: widget puro. Ganha layout responsivo, acessibilidade, ferramentas

e um sistema só.

  • Por frame: Flame. Evita reimplementar laço com delta de tempo, ciclo de vida,

colisão e câmera.

  • Flame é um widget, não um substituto do Flutter. A decisão é por tela.
  • Se alguém vai desenhar fases, o que falta é editor — e aí a conversa é sobre

motor completo.

  • Não adote motor por precaução. Comece simples e mova só a tela de partida.

Perguntas frequentes

Flame substitui o Flutter?

Não. Flame roda dentro do Flutter, num widget. Isso é a maior vantagem dele: o menu, a loja e as telas de configuração continuam sendo Flutter normal, com os widgets que você já sabe usar.

Dá para fazer jogo só com AnimationController?

Dá, e é a escolha certa mais vezes do que parece. Jogo de turno, puzzle, cartas, merge e a maior parte do idle não precisam de laço de jogo por frame. Precisam de estado e de transição bem-feita.

Quando Flame começa a valer?

Quando você precisa de atualização por frame com muitos objetos, detecção de colisão contínua ou controle fino de câmera. Se o seu jogo tem essas três coisas, escrever à mão é reimplementar Flame pior.

E quando nem Flame resolve?

Quando o jogo precisa de física, tilemap, editor de cena e ferramenta de nível. Aí a conversa não é sobre biblioteca, é sobre motor completo — e vale sair do Flutter.