Roll It é um experimento do Chrome que recria um jogo clássico de tabuleiro usando apenas o navegador no smartphone e no computador. O navegador do smartphone permite mirar e rolar a bola com um movimento do pulso, enquanto o navegador do computador renderiza os gráficos em tempo real do jogo Roll It com WebGL e Canvas. Os dois dispositivos se comunicam por meio de Websockets. Nenhum app. Nenhum download. Nenhum token. Você só precisa de um navegador moderno.
Com a direção do Google Creative Lab, a Legwork desenvolveu a experiência do usuário, as interfaces e o ambiente do jogo. Em seguida, ela se uniu ao parceiro de desenvolvimento Mode Set para criar o Roll It. Durante a duração do projeto, houve vários desafios únicos. Neste artigo, apresentamos algumas das técnicas que usamos, truques que descobrimos e lições que aprendemos ao criar o Roll It.
Fluxo de trabalho 3D
Uma das dificuldades no início foi descobrir a melhor maneira de levar modelos 3D do nosso software para um formato de arquivo pronto para a Web. Depois de criar os recursos no Cinema 4D, os modelos foram simplificados e convertidos em malhas de polígonos baixos. Cada malha recebeu determinadas tags de seleção de polígonos para diferenciar as partes do objeto para colorir e texturizar. Em seguida, exportamos como um arquivo Collada 1.5 (.dae) e importamos para o Blender, um programa 3D de código aberto, para criar arquivos compatíveis com o three.js. Depois de garantir que nossos modelos foram importados corretamente, exportamos a malha como um arquivo JSON e a iluminação foi aplicada usando o código. Confira as etapas detalhadas que tomamos:
Como escrever o código
O Roll It foi desenvolvido com bibliotecas de código aberto e é executado de forma nativa em navegadores modernos. Com tecnologias como WebGL e WebSockets, a Web está se aproximando de experiências multimídia e de jogos com qualidade de console. A facilidade e o conforto com que os desenvolvedores podem criar essas experiências estão avançando à medida que ferramentas mais modernas ficam disponíveis para o desenvolvimento em HTML.
Ambiente para desenvolvedores
A maior parte do código original do Roll It foi escrito com CoffeeScript, uma linguagem limpa e concisa que é transcompilada para JavaScript bem formado e linted. O CoffeeScript se destaca no desenvolvimento de POO com um ótimo modelo de herança e um processamento de escopo mais limpo. O CSS foi escrito com o framework SASS, que oferece ao desenvolvedor várias ferramentas excelentes para aprimorar e gerenciar as folhas de estilo de um projeto. Adicionar esses sistemas ao processo de build leva um pouco de tempo para configurar, mas o resultado vale a pena, especialmente para um projeto maior como o Roll It. Configuramos um servidor Ruby on Rails para compilar automaticamente nossos recursos durante o desenvolvimento. Assim, todas essas etapas de compilação ficaram transparentes.
Além de criar um ambiente de programação simplificado e confortável, otimizamos os recursos manualmente para minimizar as solicitações e carregar o site mais rápido. Passamos todas as imagens por alguns programas de compactação: ImageOptim e ImageAlpha. Cada programa otimiza as imagens de uma maneira diferente: sem perda e com perda, respectivamente. Com a combinação certa de configurações, é possível reduzir significativamente o tamanho do arquivo de uma imagem. Isso não apenas economiza largura de banda ao carregar imagens externas, mas, depois de otimizadas, as imagens são convertidas em strings codificadas em base64 muito menores para incorporação inline em HTML, CSS e JavaScript. No que diz respeito à codificação base64, também incorporamos nossos arquivos de fontes WOFF e SVG Open Sans diretamente no CSS usando essa técnica, o que resultou em ainda menos solicitações totais.
A cena 3D com física ativada
A THREE.js é uma biblioteca JavaScript 3D onipresente para a Web. Ele reúne otimizações de WebGL de baixo nível e matemática 3D baseada em hardware que permitem que meros mortais criem facilmente cenas 3D interativas bem iluminadas e bonitas sem precisar escrever shaders personalizados ou realizar transformações manuais de matriz. O Physijs é um wrapper específico do THREE.js para uma biblioteca de física C++ conhecida que foi traduzida para JavaScript. Aproveitamos essa biblioteca para simular a bola rolando, pulando e quicando em direção ao destino em 3D.
Desde o início, nosso objetivo era não apenas tornar a experiência física de rolar a bola realista, mas também garantir que os objetos no jogo parecessem reais. Isso exigiu muitas iterações para ajustar a gravidade geral da cena do Physijs, a velocidade da bola enquanto ela rola do arremesso do jogador, a inclinação do salto da pista e as propriedades de atrito e restituição (rebote) dos materiais da bola e da pista. A combinação de mais gravidade e velocidade resultou em uma experiência de jogo mais realista.
Alisando
A maioria das combinações modernas de navegador e placa de vídeo aproveita o anti-aliasing nativo baseado em hardware no ambiente WebGL, mas algumas não funcionam bem. Caso o anti-aliasing não funcione de forma nativa, todas as bordas duras e contrastadas na cena do THREE.js serão irregulares e feias (pelo menos para nossos olhos).
Felizmente, há uma correção: usando um snippet de código, podemos detectar se a plataforma oferece suporte nativo ao antialiasing. Se sim, podemos continuar. Caso contrário, há uma série de shaders de pós-processamento que vêm com o THREE.js que podem nos ajudar. Mais especificamente, o filtro de anti-aliasing FXAA. Ao redesenhar a cena renderizada em cada frame com esse sombreador, geralmente temos uma aparência muito mais suave das linhas e bordas. Confira a demonstração abaixo:
// Check for native platform antialias support via the THREE renderer
// from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing
var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;
Controles de jogos baseados em acelerômetro
Grande parte da magia de Roll It vem do gesto de rolar a bola que o jogador realiza com um smartphone. Os dispositivos móveis têm acesso ao acelerômetro no navegador há algum tempo, mas, como indústria, estamos apenas começando a explorar o reconhecimento de gestos baseados em movimento na Web. Estamos um pouco limitados pelos dados fornecidos pelo acelerômetro do smartphone, mas com um pouco de criatividade podemos criar novas experiências.
A detecção do gesto principal de "rolar" do Roll It começa com o rastreamento das 10 atualizações mais recentes do acelerômetro que vêm do evento deviceorientation
da janela. Subtraindo o valor de inclinação anterior do valor de inclinação atual, armazenamos a diferença de ângulo entre os eventos. Em seguida, somando constantemente os últimos dez deltas de ângulo, podemos detectar a rotação contínua à medida que o smartphone se move pelo espaço. Quando o smartphone ultrapassa um limite de mudança de ângulo de varredura, acionamos um giro. Depois, encontrando a maior delta de inclinação única nessa varredura, podemos estimar a velocidade da bola. No Roll It, essa velocidade é normalizada usando carimbos de data/hora que são anexados a cada atualização do acelerômetro. Isso ajuda a suavizar a velocidade variável em que as atualizações do acelerômetro são transmitidas para o navegador em diferentes dispositivos.
Comunicação de WebSockets
Quando o jogador rola a bola com o smartphone, uma mensagem é enviada do smartphone para o laptop, indicando que a bola deve ser lançada. Essa mensagem "roll" é enviada por um objeto de dados JSON usando uma conexão WebSocket entre as duas máquinas. Os dados JSON são pequenos, consistindo principalmente de um tipo de mensagem, velocidade de lançamento e direção de mira.
{
"type": "device:ball-thrown",
"speed": 0.5,
"aim": 0.1
}
Toda a comunicação entre o laptop e o smartphone acontece por meio de pequenas mensagens JSON como esta. Toda vez que o jogo atualiza o estado no computador ou o usuário inclina ou toca em um botão no smartphone, uma mensagem do WebSocket é transmitida entre as máquinas. Para manter essa comunicação simples e fácil de gerenciar, as mensagens WebSockets são transmitidas usando um único ponto de saída de qualquer navegador. Por outro lado, há um único ponto de entrada no navegador receptor, com um objeto WebSocket que processa todas as mensagens recebidas e enviadas em ambas as extremidades. Quando uma mensagem do WebSocket é recebida, os dados JSON são transmitidos novamente no app JavaScript usando o método trigger()
do jQuery. Nesse ponto, os dados recebidos se comportam como qualquer outro evento DOM personalizado e podem ser coletados e processados por qualquer outro objeto no aplicativo.
var websocket = new WebSocket(serverIPAddress);
// rebroadcast incoming WebSocket messages with a global event via jQuery
websocket.onmessage = function(e) {
if (e.data) {
var obj = JSON.parse(e.data);
$(document).trigger(data.type, obj);
}
};
// broadcast outgoing WebSocket messages by passing in a native .js object
var broadcast = function(obj) {
websocket.send(JSON.stringify(obj));
};
Os servidores WebSocket do Roll It são criados em tempo real quando dois dispositivos são sincronizados com um código de jogo. O back-end do Roll It foi criado na plataforma Google Compute Engine e App Engine usando Go.
Telas de menu de inclinação
Além das mensagens WebSocket orientadas a eventos usadas durante o jogo, os menus do Roll It são controlados inclinando o smartphone e tocando em um botão para confirmar uma seleção. Isso requer um fluxo mais consistente de dados de inclinação transmitidos do smartphone para o laptop. Para reduzir a largura de banda e evitar o envio de atualizações desnecessárias, essas mensagens só são enviadas se a inclinação do dispositivo mudar mais de alguns graus. Não há motivo para enviar um stream de dados de inclinação se o smartphone estiver plano em uma mesa. A taxa de transmissão também é limitada. Não são enviadas mais de 15 mensagens WebSockets por segundo no Roll It, mesmo que o dispositivo esteja sendo inclinado.
Depois que os valores de inclinação são detectados no computador, eles são interpolados ao longo do tempo usando requestAnimationFrame
para manter a sensação de fluidez. O resultado final é um menu rotativo e uma bolinha que rola para ajudar a indicar a seleção do usuário. À medida que o smartphone envia dados de inclinação, esses elementos DOM são atualizados em tempo real recalculando uma transformação CSS dentro do loop requestAnimationFrame
. O contêiner do menu simplesmente gira, mas a bola parece rolar pelo chão. Para conseguir esse efeito, implementamos algumas trigonometrias básicas para relacionar a coordenada x das bolas à rotação delas. A equação simples é: rotações = x / (diâmetro * π)
Conclusão
O Roll It é um sinal dos tempos. Entre os projetos de código aberto que impulsionaram o desenvolvimento, a capacidade de processamento dos dispositivos nas nossas mesas e nos nossos bolsos e o estado da Web como plataforma, é um momento realmente empolgante e transformador estar conectado na Web aberta. Há apenas alguns anos, grande parte dessa tecnologia só existia em sistemas proprietários, indisponíveis para uso e distribuição livres. Hoje, experiências complexas podem ser realizadas com menos trabalho e mais imaginação, à medida que criamos e compartilhamos novas peças do quebra-cabeça todos os dias. O que você está esperando? Crie algo incrível e compartilhe com o mundo!