Jogos com webcam: como criei um jogo de corrida de dinossauro
Eu queria fazer um jogo de corrida em que apertar uma tecla não valesse como correr. Se o jogador parasse de se mexer, o personagem tinha que parar também. Se ele engatasse outra arrancada, a fuga deveria ficar mais fácil. E se ele só balançasse os braços para a câmera, o jogo precisava notar a diferença.
Essa ideia virou o Dino Survival, um jogo de navegador em que você corre parado para escapar de um T-Rex. Dito numa frase, parece simples. Mas para construí-lo tive que responder a uma pergunta bem mais difícil: como fazer a webcam transformar um corpo em movimento num controle que pareça justo?
Jogo de webcam pede outro tipo de controle
A maioria dos jogos de corrida infinita reduz o movimento a um botão, um deslize ou uma velocidade automática para a frente. Isso é útil porque a entrada é exata. Um botão está apertado ou solto.
Um corpo é bem mais bagunçado. Cada pessoa tem alturas, tamanhos de cômodo, ângulos de câmera e jeitos de correr diferentes. Os joelhos podem sumir abaixo do quadro. A roupa pode esconder uma articulação. Uma câmera com pouca luz pode fazer um ponto tremer mesmo com a pessoa parada.
Então não dava para ligar uma pose direto a uma velocidade. Eu precisava de um pipeline que observasse o movimento ao longo do tempo, descartasse o ruído e ainda respondesse rápido o bastante para o jogador sentir que está no controle:
- Pedir ao navegador acesso à câmera.
- Estimar os pontos do corpo em cada quadro de vídeo.
- Medir o movimento alternado das pernas e o movimento do corpo todo.
- Converter os passos por minuto recentes num ritmo de jogo estável.
- Usar esse ritmo para mover o corredor e mudar a distância até o dinossauro.
O navegador cuida da permissão da câmera por meio de MediaDevices.getUserMedia(). O Dino Survival pede só vídeo e usa a câmera frontal quando há uma. Os quadros ao vivo são então processados pelo modelo de pose no navegador.
Pontos de pose não são corrida
O Dino Survival usa o MediaPipe Pose Landmarker em modo de vídeo. O modelo pode devolver 33 pontos do corpo, mas mais dados não dão automaticamente um controle de jogo melhor.
Para a cadência, eu foco num grupo menor: ombros, quadris, joelhos e tornozelos. Os ombros e os quadris me dão um eixo aproximado do tronco. Os joelhos e os tornozelos mostram como as pernas se movem em relação a esse eixo.
Essa medição relativa faz diferença. Se eu só medisse a altura em que um joelho aparece na tela, um celular inclinado ou uma pessoa fora do centro poderia mudar o resultado. Se eu projeto o movimento das pernas no eixo do próprio tronco, o detector depende bem menos de como a câmera está posicionada.
O jogo também confere se os dois quadris e os dois joelhos estão visíveis. Se não estiverem, ele pede que o jogador dê um passo para trás, em vez de inventar um ritmo, sem avisar, com dados incompletos. Num jogo de controle por movimento, é melhor ser honesto com o jogador do que fingir que a entrada é confiável.
Transformando pernas alternadas em cadência
Correr parado cria um padrão que se repete. Um joelho sobe, chega a um pico e desce. Depois a outra perna faz o mesmo. O detector observa o movimento do joelho e do tornozelo e procura esses picos alternados.
Uso limites adaptativos para cada perna, porque um número fixo não serve para todo corpo nem para toda câmera. Uma pessoa alta pode gerar na tela um movimento bem maior do que uma mais baixa que está mais longe. O detector aprende uma faixa local útil, enquanto um teto rígido impede que essa adaptação fique permissiva demais.
Depois de um pico válido, a mesma perna tem um curto período refratário de 130 milissegundos. Isso impede que a tremedeira dos pontos no topo de uma elevação de joelho vire dois ou três passos imaginários. Os passos válidos entram numa janela móvel de três segundos, longa o bastante para suavizar o número, mas curta o bastante para notar uma mudança real de esforço.
Se não houver nenhum passo por cerca de 1,1 segundo, a cadência volta de uma vez para parado. Prefiro essa zeragem imediata a um decaimento longo e lento. Quando o jogador para, o jogo deve parar.
Como impedi que balançar os braços virasse velocidade máxima
Os primeiros sistemas de movimento costumam premiar qualquer atividade no quadro. Isso abre um atalho óbvio (deixar os pés parados e mexer as mãos) e ainda faz a câmera tremendo parecer exercício.
O Dino Survival acrescenta uma segunda barreira baseada nos quadris. Ela procura um quique vertical de verdade do corpo, numa janela curta. A cadência só conta quando o padrão alternado das pernas e esse sinal de movimento maior concordam.
Não quero dar nota para a técnica de corrida de ninguém. Só exijo uma prova de que a parte de baixo do corpo está fazendo o trabalho. Mexer só os braços não abre a barreira, e um ruído pequeno na estimativa de pose não faz o corredor andar.
Uma das maiores lições que tirei criando jogos de webcam: é que uma boa entrada não é a que detecta mais movimento. É a que detecta o movimento certo e explica com clareza quando a câmera não consegue enxergá-lo.
De passos por minuto a uma perseguição de dinossauro
O detector de cadência produz passos por minuto, mas o jogo não precisa de uma medição de laboratório. Precisa de um sinal claro e jogável. Mapeio o resultado em três faixas de esforço fáceis de entender: trote a cerca de 70 passos por minuto, corrida a 120 e velocidade máxima a 160.
Essas faixas viram um ritmo normalizado. O motor de sobrevivência usa esse ritmo para levar o jogador em direção a uma meta de fuga de 50 unidades. Ao mesmo tempo, o dinossauro tem a sua própria velocidade, que aumenta durante a corrida.
A distância varia conforme a diferença entre essas duas velocidades. Corra mais que o dinossauro e você abre vantagem. Pegue leve e ele começa a se aproximar. Chegue ao jipe e você escapa. Deixe a distância chegar a zero e a perseguição acaba.
É isso que faz o jogo parecer diferente de um jogo de corrida de dinossauro qualquer. O dinossauro não é só um cronômetro com dentes. É uma explicação visual do esforço atual do jogador.
O mundo só se move quando o jogador se move
A trilha é feita de uma sequência de quadros da selva. Eu escolho o quadro pela distância acumulada, e não pelo relógio. Se o jogador para de correr, o cenário congela. Volte a correr e a trilha recomeça a passar sob os pés do corredor.
O tamanho e a posição aparentes do dinossauro estão ligados à distância. Quanto mais perto ele chega, mais espaço ocupa na cena. A poeira, as linhas de velocidade e o painel de ritmo apoiam a mesma mensagem. Vários sinais pequenos respondem à mesma pergunta: será que estou escapando?
O ciclo de desenho usa requestAnimationFrame(), que pede ao navegador para executar o trabalho de animação antes da próxima atualização da tela. Uso o carimbo de tempo do callback para calcular o tempo decorrido. Assim o movimento depende do tempo, e não de todo aparelho desenhar o mesmo número de quadros por segundo.
Também usei um corredor pré-renderizado, em vez de recortar a pessoa ao vivo e colocá-la na cena a cada quadro. Isso alivia o processamento nos aparelhos móveis e dá ao jogo um personagem consistente. A webcam é o controle, não a arte final.
Por que a calibração faz parte do design do jogo
Configurar a câmera não é uma tela técnica que dá para esconder do jogador. É a primeira fase.
O Dino Survival mostra um guia de enquadramento e espera até os pontos necessários ficarem visíveis. Ele explica quando é preciso dar um passo para trás e dá ao jogador uma contagem regressiva curta antes da perseguição. Esse momento estabelece o combinado: deixe a parte de baixo do corpo visível, corra parado, e o jogo acompanha.
Há também um modo de demonstração com teclado. Ele permite explorar o jogo sem permissão de câmera, testar num aparelho sem suporte ou só entender as regras antes. A experiência completa continua sendo a versão com câmera, porque a ligação física entre esforço e fuga é o coração do jogo.
O que aprendi construindo o Dino Survival
A parte mais difícil não foi desenhar um T-Rex. Foi decidir o que deveria contar como um passo.
Um controle de corpo confiável precisa de várias verificações modestas trabalhando juntas. Os pontos estabelecem onde o corpo está. Os picos alternados de joelho e tornozelo sugerem a cadência. O movimento dos quadris confirma que o jogador está mesmo correndo. Uma janela móvel suaviza o resultado. Uma volta rápida para "parado" mantém honesto o ato de parar. O motor do jogo então transforma esse sinal numa distância que o jogador entende sem precisar de manual.
Para mim, é esse o encanto do controle por movimento no navegador: a tecnologia some quando o retorno está certo. Você não pensa em pontos, limites ou carimbos de tempo dos quadros. Você vê um dinossauro, ouve ele se aproximando e corre.
Para o lado do design e da pesquisa, leia por que considero o Dino Survival um bom jogo de exercício.
Você pode jogar Dino Survival de graça no navegador. Não precisa baixar nada. Se quiser ver como o mesmo pipeline de webcam lida com o movimento da parte de cima do corpo, leia como criei o Monster Punch como um jogo de boxe online. Para mais jogos que começam na hora, veja o meu guia de jogos grátis sem download.