Quase todo jogo de navegador desenha em uma tag canvas. Mas o navegador já tem um motor gráfico muito bom para elementos comuns. Para jogos com poucas dezenas de objetos na tela, dá para usá-lo diretamente.
A regra de ouro: só transform e opacity
Mudar left, top ou width obriga o navegador a recalcular o layout. Mudar transform e opacity não: o elemento vira uma camada e a placa de vídeo só a reposiciona. No nosso jogo, o carro, as zonas de raio e os obstáculos se movem exclusivamente com translate3d.
Estrada infinita com um único elemento
As faixas da pista são um fundo repetido. A cada quadro deslocamos esse elemento alguns pixels para baixo e, ao completar um ciclo do padrão, voltamos ao zero. O olho não percebe o salto, e a estrada parece não ter fim.
Perspectiva de graça
A sensação de profundidade vem de duas linhas de CSS: perspective no contêiner e rotateX na pista. Tudo o que está dentro dela herda a inclinação, sem nenhuma conta de projeção em JavaScript.
Colisão em unidades próprias
Com a pista inclinada, pixels de tela deixam de ser confiáveis. A lógica trabalha em “unidades de pista”, de −1 a +1, e só converte para pixels ao desenhar. Colisão vira comparar dois intervalos.
Onde entra o SVG
O raio é uma linha quebrada gerada a cada descarga, com pontos sorteados entre a mão do Zeus e o alvo. É um elemento que vive um terço de segundo e some.
Quando não vale a pena
Centenas de partículas, mapas de blocos enormes ou efeitos por pixel pedem canvas ou WebGL. A abordagem com elementos HTML brilha em jogos de poucos objetos grandes, onde ganha em nitidez, acessibilidade e tamanho de arquivo.
Quer ver na prática? Leia os bastidores do desenvolvimento ou jogue as demos, feitas do mesmo jeito.