Como adicionar controles de toque a um jogo de navegador feito só para teclado?
Coloque sobre o jogo uma camada de toque separada que envie a ele as entradas que ele já entende. Veja como fizemos isso no KittenGalaxy e o que ainda não testamos.

Adicione uma camada separada de controles na tela que transforme toques nas entradas que o seu jogo já trata, e mostre controles diferentes em cada tela do jogo. Você não precisa reescrever o jogo. Foi isso que fizemos para tornar o KittenGalaxy jogável em celulares, e este artigo percorre as decisões, incluindo as partes que ainda não conseguimos testar.
O que o jogo esperava antes?
KittenGalaxy é um jogo de tiro arcade escrito como um único arquivo JavaScript que desenha em um canvas. Toda a entrada chegava de três formas: teclas pressionadas para voar, atirar e usar os menus; caracteres digitados para o nome de um piloto; e cliques do mouse para a lista da loja e para um teclado numérico desenhado no canvas nos desafios de matemática.
Em um celular, isso deixa o jogador sem nada para pressionar. Não há teclas, e as teclas numéricas do canvas, desenhadas com 38 unidades de largura em um campo de 720 unidades, ficam com cerca de 20 pixels CSS em um celular de 375 pixels de largura. É pequeno demais para acertar com segurança.
O toque deve alterar um estado de entrada compartilhado ou enviar eventos de teclado?
Há dois desenhos comuns.
| Abordagem | Como funciona | Quando é boa |
|---|---|---|
| Estado de entrada compartilhado | Os tratadores de teclado e de toque ligam indicadores como left ou fire; o loop do jogo lê apenas os indicadores | O código do jogo é seu e você pode mudar como ele lê a entrada |
| Eventos de teclado sintéticos | A camada de toque dispara eventos keydown e keyup; os tratadores que o jogo já tem os recebem | O código do jogo deve continuar como está |
O estado compartilhado é o desenho mais limpo e, se você está começando um jogo hoje, faça assim. Escolhemos os eventos de teclado sintéticos por um motivo: o KittenGalaxy é desenvolvido em outro lugar, e mantemos o arquivo dele byte a byte como o recebemos, para que adotar uma versão mais nova nunca signifique refazer as nossas alterações. Eventos criados por script chegam, sim, aos tratadores comuns. Eles não disparam as ações padrão do navegador, e um jogo não precisa delas.
A camada de toque também precisa saber em que tela o jogo está. Para isso, nossa etapa de build acrescenta um pequeno objeto somente leitura que expõe alguns valores, como o estado atual e se há um foguete equipado. Nada nele pode alterar o jogo.

De quais controles cada tela precisa?
Um conjunto fixo de botões costuma ser a primeira tentativa, e falha assim que o jogo tem um menu. Liste cada tela e o que o jogador precisa conseguir fazer nela.
| Tela | O que o jogador precisa | O que mostramos |
|---|---|---|
| Menu | Começar, trocar ou adicionar um piloto | Um botão principal grande, mais outros pequenos que só aparecem quando fazem sentido |
| Nome do piloto | Digitar um nome | Um campo de texto de verdade, para o celular mostrar o teclado |
| Voo | Mover, atirar, usar extras, pausar | Um direcional para o polegar, tiro automático e botões de extras só depois de adquiridos |
| Loja | Navegar e comprar | Botões de abas e setas; tocar em uma linha a seleciona, tocar de novo compra |
| Desafio de matemática | Informar um número | Um teclado numérico em tamanho real |
| Fim de jogo, finais | Continuar ou sair | Dois botões |
Três detalhes importaram mais do que esperávamos.
Use um campo de texto de verdade para texto. Só um campo em foco faz o celular mostrar o teclado. Mantemos as teclas desse campo longe do jogo e digitamos o nome pronto no jogo de uma vez só.
Um dedo não consegue pairar. Com o mouse, apontar para uma linha da loja a seleciona e clicar a compra. Um toque faz as duas coisas ao mesmo tempo, o que facilita compras acidentais. A camada transforma o primeiro toque em uma linha em seleção e deixa o segundo passar como a compra.
Esconda o que não se aplica. O botão do foguete aparece quando há um foguete equipado e o da bomba quando há uma bomba. Menos botões significa botões maiores.
Como se constrói um direcional para o polegar?
A nave do jogo se move em oito direções, como nas setas, então o direcional só precisa decidir quais setas estão pressionadas. O nosso aparece onde o polegar encosta, ignora movimentos dentro de uma zona morta de 12 pixels e trata uma direção como pressionada quando o polegar está longe o bastante naquele eixo:
const DEAD = 12;
function steer(dx, dy) {
const far = Math.hypot(dx, dy) > DEAD;
const want = {
ArrowLeft: far && dx < 0 && Math.abs(dx) >= Math.abs(dy) * 0.41,
ArrowRight: far && dx > 0 && Math.abs(dx) >= Math.abs(dy) * 0.41,
ArrowUp: far && dy < 0 && Math.abs(dy) >= Math.abs(dx) * 0.41,
ArrowDown: far && dy > 0 && Math.abs(dy) >= Math.abs(dx) * 0.41,
};
// press the keys that became true, release the ones that became false
}
O 0,41 é a tangente de 22,5 graus, que divide o círculo em oito fatias iguais. Quando o polegar passa da borda, o centro do direcional o acompanha, então inverter a direção exige um movimento curto em vez de um longo.
Usamos eventos de ponteiro, que cobrem toque, caneta e mouse com um único conjunto de tratadores, e captura de ponteiro, para que o direcional continue recebendo um polegar que escorrega para fora dele. O tiro é automático por padrão, com uma chave para quem prefere um botão de tiro: manter um polegar pressionado por uma sessão inteira cansa, e um jogo de tiro perde pouco por atirar o tempo todo.
O que impede o navegador de brigar com o jogo?
Um navegador trata toques como rolagem, zoom e seleção de texto, a menos que seja instruído do contrário.
- Defina [
touch-action: none](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/touch-action) no jogo e nos controles, para que os arrastos sejam seus. - Desative a seleção de texto e o menu de toque longo sobre o jogo.
- Solte todas as teclas seguradas quando a janela perder o foco. Caso contrário, a nave continua voando para a esquerda depois que uma notificação toma a tela.
- Inicie o som a partir de um toque de verdade. Os navegadores só permitem áudio depois que o jogador interage com a página, então o primeiro toque também acorda o áudio do jogo.
- Atualize os controles por um temporizador, não só pelo loop de desenho, para que os botões certos estejam lá antes de o primeiro quadro ser desenhado.
- Use as faixas que o jogo deixa vazias. Em retrato, nosso campo quadrado fica no meio, então os controles vão nas faixas pretas de cima e de baixo. Em paisagem, vão nos cantos e ficam discretos.
O que testamos e o que não testamos?
No dia do lançamento, 8 de outubro de 2026, conferimos a camada de toque em um navegador de computador ajustado para o tamanho de celular, em retrato (375 × 812) e paisagem (812 × 375), conduzindo-a com toques programados: criar um piloto pelo campo de texto, começar uma partida, as oito direções do direcional, a loja e responder a uma pergunta de matemática no teclado numérico.
Ainda não jogamos em um celular ou tablet de verdade. A emulação não mostra como o direcional se comporta sob um polegar real, como o teclado de cada celular age nem como um aparelho mais lento se sai. A página do jogo diz exatamente isso na opção de navegador de celular, e vamos atualizá-la quando aparelhos reais forem testados. Se você jogar no seu celular, uma avaliação dizendo o aparelho e o que aconteceu é a coisa mais útil que você pode enviar.
Perguntas comuns
Preciso de um motor de jogos para controles de toque? Não. Os botões são elementos HTML comuns posicionados sobre o canvas, e o navegador descobre qual foi tocado.
Os botões devem ser desenhados no canvas ou feitos em HTML? Em HTML, na maioria dos casos. Você ganha detecção de toque, multitoque e rótulos de acessibilidade sem escrevê-los, e pode mudar o estilo com CSS.
Qual deve ser o tamanho de um botão de toque? Os botões pressionados durante o jogo têm pelo menos 46 pixels CSS de cada lado em retrato, e os principais são maiores; alguns botões utilitários nos cantos são menores de propósito. As teclas do canvas que substituímos tinham cerca de 20.
Os jogadores vão descobrir um gesto escondido? Parta do princípio de que não. Cada ação na nossa camada tem um botão visível e com rótulo.
Posso colocar um jogo no HeapPlay antes de os controles para celular ficarem prontos? Sim. Cada forma de jogar é listada e conferida separadamente, então você pode enviar o seu jogo com uma opção para computador agora e adicionar uma para celular depois. Desenvolvedores verificados podem então registrar cada versão por conta própria; veja o que os desenvolvedores recebem.
touch-controls mobile browser-games
Está fazendo um jogo? Envie-o ao HeapPlay e veja o que os desenvolvedores recebem.