Um jogo de proximidade inspirado em Campo minado.
A equipe que criou o squoosh.app está de volta! Dessa vez, criamos um jogo baseado na Web chamado PROXX (proxx.app). PROXX é um jogo de proximidade inspirado no lendário jogo Minesweeper. O jogo se passa no espaço, e sua tarefa é descobrir onde estão os buracos negros. Ele funciona em todos os tipos de dispositivos, de computadores a feature phones. Os usuários podem jogar o jogo usando um mouse, teclado, botão direcional ou até mesmo um leitor de tela.
Nossa linha de base
Antes de criar o jogo, definimos as seguintes metas e orçamentos para o app:
- Mesmo núcleo de experiência: todos os dispositivos precisam funcionar da mesma forma.
- Acessível: mouse, teclado, toque, direcional, leitores de tela
- Performant:
- Menos de 25 KB de payload inicial
- Menos de 5 segundos de TTI (tempo para interação) em 3G lento
- Animação consistente de 60 fps
Web Workers
O jogo consiste em quatro entidades principais: a lógica principal do jogo, o serviço de interface, o serviço de estado e os gráficos de animação. Como sabíamos desde o início que precisaria executar gráficos altamente animados na linha de execução principal, movemos a lógica do jogo e o serviço de estado para um worker da Web para manter a linha de execução principal o mais livre possível.
Pré-renderização do tempo de build
Nossa interface foi criada com o Preact, porque ele permite atingir nossa meta agressiva de um payload inicial com menos de 25 KB. Para oferecer uma boa experiência de carregamento inicial, decidimos pré-renderizar nossa primeira visualização. Fazemos a pré-renderização no momento do build usando o Puppeteer para acessar a página principal e permitir que o preact preencha o DOM. O DOM resultante é serializado em HTML e salvo como index.html.
Tela para animação, DOM (invisível) para acessibilidade
Renderizamos os gráficos do jogo em uma tela usando o WebGL. Uma tela é responsável pela animação de plano de fundo e outra pela grade do jogo na parte de cima. Também temos uma tabela HTML com botões por motivos de acessibilidade, que fica acima das duas telas, mas é invisível (opacidade: 0). Embora o que você vê seja uma renderização de tela do estado do jogo, o jogador está interagendo com a tabela DOM invisível, permitindo que você anexe listeners de eventos e confie no gerenciamento de foco do navegador.
Ao manter o elemento DOM na tela, podemos usar os recursos
de acessibilidade integrados aos navegadores. Por exemplo, ao definir role="grid"
na tabela
de jogos, os leitores de tela podem anunciar a linha e a coluna da célula em foco
sem que precisemos implementar isso.
Agrupamento para agrupamento e divisão de código
O tamanho total do app é de 100 KB compactado em gzip. Desse total, 20 KB são para o payload inicial (index.html). Usamos o Rollup.js para este projeto. Temos dependências compartilhadas entre a linha de execução principal e o worker da Web, e o Rollup pode colocar essas dependências compartilhadas em um bloco separado que precisa ser carregado apenas uma vez. Outros bundlers, como o Webpack, duplicam as dependências compartilhadas, o que resulta em carregamento duplo.
Suporte a feature phones
Smartphones básicos inteligentes, como os KaiOS, estão ganhando popularidade rapidamente. Esses são dispositivos com recursos limitados, mas nossa abordagem de usar workers da Web sempre que possível nos permitiu tornar a experiência altamente responsiva nesses smartphones também. Como os feature phones vêm com uma interface de entrada diferente (D-pad e teclas numéricas, sem tela touchscreen), também implementamos a interface baseada em teclas.
A seguir
Foi muito bom criar esse jogo a tempo para o Google I/O 2019, então vamos tirar um merecido tempo para descansar, mas planejamos voltar com uma documentação mais detalhada sobre cada uma dessas áreas do jogo.
Enquanto isso, confira a palestra que Mariko fez na I/O sobre esse projeto.
Procure o código no repositório do GitHub do proxx (link em inglês).
Saúde! Surma, Jake, Mariko