A-Frame é uma estrutura baseada na Web que permite criar vários aplicativos, jogos, cenas em realidade virtual (VR). Todos os itens acima estarão disponíveis diretamente no navegador do seu capacete de VR. Essa ferramenta será útil para quem deseja desenvolver jogos de RV em um navegador e, por exemplo, pode ser útil como plataforma para a criação de aplicativos, sites e páginas de destino de RV na Web. Os usos do Web BP são limitados apenas pela sua imaginação. De improviso, posso trazer algumas áreas da atividade humana em que a BP pode ser útil: educação, medicina, esportes, vendas, lazer.
O que tem dentro?
O A-Frame não é gravado a partir de 0 no WebGL puro, é baseado na biblioteca
Three.js . Portanto, recomendo que você entenda os conceitos básicos do Three.js antes de começar a trabalhar com o A-Frame, embora isso não seja necessário, pois o A-Frame foi projetado para que você menos pense na geometria da renderização e se concentre mais na lógica do seu aplicativo. . É por isso que ele, de fato, e a estrutura.
Para isso, o A-Frame postula três pontos principais, sobre os quais falaremos mais adiante.
A-Frame funciona com HTML
Muitos elementos básicos do A-Frame, como cena, câmera, caixa, esfera, etc., são adicionados à cena por meio de tags com o mesmo nome com o prefixo
a- . Cada item semelhante é registrado como personalizado. No momento, o A-Frame (0.8.0) usa a especificação v0.
<a-scene> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere> </a-scene>
Este pequeno pedaço de código desenhará uma cena do WebGL na qual dois objetos serão adicionados: um cubo e uma esfera com os parâmetros fornecidos. Além dos dois elementos mencionados acima, existem várias outras primitivas que podem ser adicionadas à cena da mesma maneira:
<a-círculo>, <a-cone>, <a-cylinder>, <a-dodecahedron>, <a-icosahedron> , <a-octaedro>, <aplane>, <a-ring>, <a-tetraedro>, <nó-de -toro>, <-toro>, <-triangulo> . Também no A-Frame, existem vários outros elementos que executam certas funções:
- <a-camera> - cria uma câmera. Somente a câmera em perspectiva (PerspectiveCamera) é atualmente suportada.
- <a-obj-model>, <a-collada-model>, <a-gltf-model> - todos eles carregam e exibem modelos do formato correspondente.
- <a-cursor> - um elemento que permite executar várias ações: clique, orientação etc. O cursor está amarrado ao centro da câmera, para que esteja sempre no centro do que o usuário vê.
- <a imagem> - exibe a imagem selecionada em um plano (<aplane>).
- <a-link> é o mesmo que uma tag, apenas para uma cena 3D.
- <a-sky> - um enorme cilindro ao redor do palco que permite exibir 360 fotos. Ou você pode simplesmente preenchê-lo com um pouco de cor.
- <a-sound> - cria uma fonte de som em uma determinada posição.
- <a-text> - desenha texto simples.
- <a-video> - reproduz vídeo em um avião.
Também gostaria de observar que trabalhamos com elementos DOM e, portanto, podemos usar a API DOM padrão, incluindo querySelector, getElementById, appendChild, etc.
A-Frame usa ECS
ECS (Entity Component System) - padrão de design de aplicativos e jogos. Foi difundido apenas no segundo segmento. Como o nome indica, os três conceitos básicos de um padrão são Entidade, Componente, Sistema. Na forma clássica, eles estão interconectados da seguinte forma: temos algum objeto contêiner (Entidade) ao qual podemos adicionar componentes. Normalmente, um componente é responsável por uma parte separada da lógica. Por exemplo, temos um objeto Player, um componente Health. Este componente conterá toda a lógica associada à reposição ou perda de saúde do jogador (objeto). E sistemas, por sua vez, são necessários para gerenciar um conjunto de entidades combinadas por alguns componentes. Normalmente, um componente pode registrar uma entidade no sistema com o mesmo nome.
No A-Frame, esse padrão é implementado de maneira muito simples e elegante - com a ajuda de atributos. Todos os elementos do quadro A. -
<cena>, <caixa>, <esfera> etc. são usados como entidades, mas é claro que o elemento
<entidade> se destaca. O nome dele fala por si. Todos os outros elementos são essencialmente invólucros para componentes e são feitos para maior comodidade, pois qualquer elemento também pode ser criado usando
<a-entity> . Por exemplo
<a-box> :
<a-entity geometry="primitive: box; width: 1; height: 1; depth: 1"></a-entity>
geometria - nesse caso, é o componente que foi adicionado à entidade
<aentity> .
A própria entidade não possui nenhuma lógica (no sentido global), e o componente de
geometria o transforma essencialmente em um cubo ou em outra coisa. Outro componente não menos importante que a
geometria é o
material . Adiciona material à geometria. O material é responsável por saber se o nosso cubo brilhará como metal, se terá alguma textura, etc. No
Three.js puro
, teríamos que criar geometria separada, material separadamente e, em seguida, tudo isso precisaria ser combinado no cache. Em geral, essa abordagem economiza tempo.
Qualquer componente no A-Frame deve ser registrado globalmente através de um design especial:
AFRAME.registerComponent('hello-world', { init: function () { console.log('Hello, World!'); } });
Em seguida, esse componente pode ser adicionado à cena ou a qualquer outro elemento.
<a-entity hello-world></a-entity>
Como adicionamos o retorno de chamada
init para nosso componente, assim que o elemento for adicionado ao DOM, esse retorno de chamada funcionará e veremos nossa mensagem no console. Existem outros retornos de chamada do ciclo de vida nos componentes A-Frame. Vamos nos aprofundar neles com mais detalhes:
- update - é chamado durante a inicialização como init e ao atualizar qualquer propriedade desse componente.
- remove - chamado após remover um componente ou entidade que o contém. Ou seja, se você remover <a-entity> do DOM, todos os seus componentes chamarão remover retorno de chamada.
- tick - chamado todas as vezes antes de renderizar a cena. Dentro do loop de renderização, request requestAnimaitonFrame
- tock - chamado todas as vezes após renderizar uma cena.
- play - cada um é chamado quando a cena é retomada. Essencialmente após scene.play ();
- pausa - Chamado toda vez que uma cena é interrompida. Essencialmente após scene.pause ();
- updateSchema - chamado todas as vezes após a atualização do esquema.
Outro conceito de componente importante no A-Frame é o circuito. O diagrama descreve as propriedades do componente. É definido da seguinte forma:
AFRAME.registerComponent('my-component', { schema: { arrayProperty: {type: 'array', default: []}, integerProperty: {type: 'int', default: 5} } }
Nesse caso, nosso
componente my conterá duas propriedades,
arrayProperty e
integerProperty . Para passá-los para o componente, você precisa definir o valor do atributo correspondente.
<a-entity my-component="arrayProperty: 1,2,3; integerProperty: 7"></a-entity>
Você pode obter essas propriedades dentro do componente através da propriedade de
dados .
AFRAME.registerComponent('my-component', { schema: { arrayProperty: {type: 'array', default: []}, integerProperty: {type: 'int', default: 5} }, init: function () { console.log(this.data); } }
Para obter as propriedades de um componente da entidade à qual ele foi adicionado, você pode usar a função
getAttribute levemente modificada. Ao acessar a entidade A-Frame, ele retornará não apenas o valor da string do atributo, mas o objeto de
dados mencionado acima.
console.log(this.el.getAttribute('my-component'));
Da mesma maneira, você pode alterar as propriedades de um componente:
this.el.setAttribute('my-component',{arrayProperty: [], integerProperty: 5})
Agora vamos falar sobre sistemas. Os sistemas no quadro A são registrados da mesma maneira que os componentes:
AFRAME.registerSystem('my-system', { schema: {}, init: function () { console.log('Hello, System!'); }, });
Além do componente, o sistema possui um circuito e retornos de chamada. Somente o sistema possui apenas 5 deles:
init, play, pause, tick, tock . O sistema não precisa ser adicionado como um componente à entidade. Ele será adicionado automaticamente à cena.
this.el.sceneEl.systems['my-system'];
Se o componente tiver o mesmo nome que o sistema, o sistema estará disponível neste
sistema .
AFRAME.registerSystem('enemy', { schema: {}, init: function () {}, }); AFRAME.registerComponent('enemy', { schema: {}, init: function () { const enemySystem = this.system; }, });
Normalmente, são necessários sistemas para montar e gerenciar entidades com componentes relacionados. Aqui, em teoria, deve haver lógica relacionada a uma coleção de entidades. Por exemplo, controle a aparência dos inimigos no jogo.
A comunicação no A-Frame ocorre através dos eventos do navegador
De fato, por que reinventar a roda, se no momento existe uma ótima implementação interna de editor-assinante para elementos DOM? Os eventos do DOM permitem que você escute os dois eventos do navegador, como pressionamento de tecla, clique do mouse e outros eventos do usuário. O A-Frame nos oferece uma maneira conveniente e fácil de se comunicar entre entidades, componentes e sistemas, por meio de eventos do usuário. Para isso, cada elemento A-Frame é corrigido pela função de
emissão , são necessários três parâmetros: o
primeiro é o nome do evento, o
segundo são os dados a serem transmitidos e o
terceiro é se o evento deve aparecer.
this.el.emit('start-game', {level: 1}, false);
Você pode se inscrever neste evento da maneira usual para todos nós, usando
addEventListener: const someEntity = document.getElementById('someEntity'); someEntity.addEventListener('start-game', () => {...});
A interferência de eventos aqui é um ponto muito importante, porque às vezes duas entidades que devem se comunicar estão no mesmo nível; nesse caso, você pode adicionar um ouvinte de evento ao elemento de cena. Como você pode ver anteriormente, está disponível dentro de cada elemento através do link
sceneEl .
this.el.sceneEl.addEventListener('start-game', () => {...});
Em conclusão
Talvez isso seja tudo sobre o que eu queria falar neste artigo. O A-Frame tem muitos tópicos diferentes que podem ser abordados, mas este artigo é uma revisão e eu queria focar o leitor apenas nos pontos principais.
No próximo artigo, tentaremos criar uma cena básica para testar todo o conhecimento adquirido na prática. Obrigado a todos!