Experimente escrever um jogo em TypeScript e WebGL ou um conto sobre como um shch de back-end mergulhou em um front-end moderno

Bom dia a todos habrozhitel. Quero contar sobre como voltei a um desenvolvedor de jogos amadores após mais de 3 anos, mudando radicalmente a ferramenta (e ao longo do caminho - minha visão de mundo) e o que aconteceu com ela. Sob o corte você:


  1. Uma breve disposição de todos os fatos no início da jornada. Como a imagem "ANTES" na publicidade on-line barata "ANTES" e "DEPOIS".
  2. Um mergulho voluntário em uma interface moderna no estilo de "Onde está o dinheiro, Lebowski?!"
  3. Comichão leve em um ponto íntimo, transformando-se em um desejo ardente de aprender algo novo fazendo algo antigo.
  4. Consciência do próprio desamparo
  5. Superação
  6. Bom final, assim como nesses seus filmes.

Isenção de responsabilidade


Este artigo ficou em rascunho no github por dois anos; sua versão quase completa foi escrita no final de 2017 em busca de eventos.


Cidadão, apresente-se!


No meu artigo anterior ( https://habrahabr.ru/post/244417/ ), escrevi um pouco sobre mim e, mais especificamente, sobre como eu e o gamedev estamos conectados. De jure - de jeito nenhum, de fato - escrevo jogos e motores por prazer e participação em competições quentes e de lâmpadas. Desde então, pouco mudou.


Para uma narração mais aprofundada e forçar a atmosfera necessária, é importante que, no início deste conto, eu seja um desenvolvedor web .net profissional que possa usar html5, css3 e ... jquery. Para reforçar o inesperado "esta é a sua vez", acrescentamos que há desconfiança e repulsa pelo JavaScript, temperado com:


  • franco mal-entendido de todo esse hype em torno da linguagem;
  • um conjunto de piadas sobre digitação, obsolescência acelerada de estruturas, número + surpresas com seqüências de caracteres e muito mais. Você sabe, um conjunto tão gentil e padrão de desenvolvedores usando uma linguagem mais antiga e estabelecida (ei, eu sei que a plataforma .net é mais nova que js, mas não "adulta" no sentido literal).

Venha junto!


Setembro de 2017. Iniciei um novo trabalho quente e de lâmpadas com uma nova pilha de tecnologia (.net core web api + angular 4) e minha tarefa era apenas o back-end. A palavra Angular parecia abusiva para mim, npm e nodejs estavam fortemente associados a smoothies e uma scooter giroscópica. Timlid, vendo isso e entendendo, me ensinou um breve curso sobre como lançar todo esse shaitanismo. Como naquela piada sobre Chukchi e cães no espaço. Lembro-me dos apelidos de morcego que preciso começar (lembrando-me do npm run start, achei extremamente desnecessário para minha natureza gentil) e mergulhei em um ambiente quente e agradável. tubo LED .net core.


Outubro de 2017. O primeiro sino. Timlid diz que nosso funcionário da linha de frente cria quatro projetos imediatamente e se oferece para cortar uma seção na área administrativa para mim. Motivando isso, dizem eles, é fácil, basta repetir como foi feito para a entidade N, agora apenas para M. Para a risada dos colegas fugindo para uma scooter giroscópica e um vape para mim, lendo rapidamente um pequeno programa educacional sobre Angular, por copiar e colar e sorte, eu Parto uma seção que, com reservas, funciona. Timlid está satisfeito, estou em choque e parece que as tarefas no backend apareceram no quadro ...


Mas não. Existem muitos endossantes, já existem poucas tarefas para eles e um campo não cultivado está na frente. Uma nova tarefa, já diretamente no portal, me leva a levar a sério o assunto. Os colegas se esforçam para dobrar minhas calças e me levar a uma barbearia, e por uma semana eu mergulho em materiais de leitura sobre Angular, TypeScript, npm, webpack e muito mais. A propósito, o artigo sobre Javascript moderno para dinossauros ajudou muito - https://habrahabr.ru/company/mailru/blog/340922/ .


Depois de algum tempo, consegui fechar tarefas simples de front-end, me sentindo como um porteiro na ausência de uma empregada. Ainda rindo de piadas sobre o front-end, sugiro que meus companheiros se juntem e ouçam minha experiência com morango e banana. Todo mundo ri, mas em segredo todo mundo quer entender que tipo de bolha está acontecendo neste front-end rápido (na verdade, não).


Sem mais delongas, recontarei o artigo acima da Habr, temperando-o com meu conhecimento básico de Angular. O Mitap vem com um estrondo e, subsequentemente, passo uma série desses - sobre o front-end para o back-end, que, no entanto, não é tão importante para a nossa história. A única coisa importante é que a implementação deles me levou a um estudo mais profundo da pilha moderna de tecnologias front-end.


Comichão


No trabalho, tudo acabou, um momento bastante calmo chegou na vida familiar, e a coceira apareceu. Tais, você sabe, pequenos, ainda bastante frágeis e vivendo em algum lugar na fronteira do subconsciente. Pensamentos brilhavam na minha cabeça, dizem eles, três anos atrás, eu quase parei completamente de jogar meu hobby - jogos de programação. Mas e se você combinar novos conhecimentos e? ..


Examinei o WebGL por um longo tempo, mas antes fiquei com medo da falta de ajuda (digitação, preenchimento automático) ao usá-lo. E aqui, por favor - uma bala de prata inexistente na carne, Aquele mesmo martelo, quando levado, tudo se torna prego. TypeScript


Para mim, como uma pessoa que conhecia a dor do inferno de retorno de chamada, var self = this, bind (this), indefinido não é uma função ... Então, o TypeScript me pareceu nem mesmo uma lufada de ar fresco, mas uma espécie de mago em uma nave azul, que, descendente de céu, preguiçosamente me jogou - filho, esqueça tudo o que você sabia sobre js antes, e eu vou lhe mostrar a profundidade da toca do coelho. A analogia parece caótica e, em geral, algum tipo de mistura de outras analogias? É verdade, como o próprio TypeScript de relance.


Classes, interfaces, digitação, assíncrona, erros e erros de digitação, conclusão de código, trabalho sem pandeiro, comportamento compreensível, em vez de desencorajar a variação do tipo "foda-se-ao-escopo". É claro que, depois de um tempo, percebi que o principal patrocinador dessa felicidade não é o TypeScript, mas o próprio JavaScript, em sua versão moderna (ES6 e acima). Mas naquele momento parecia que eu havia encontrado um profeta que levaria o frontend a um brilhante, comunista o futuro. Acrescente a isso o progresso bastante sério de vários IDEs no campo do Intellisense e a assistência ao desenvolvedor, e talvez você entenda minha satisfação com o filhote.


Desamparo


O primeiro golpe sério em minha respiração foi o próprio TypeScript. Tentativas de fixá-lo a um projeto vazio me fizeram entender - não consigo entender nada de fora do angular e do angular-cli, que fazem muito trabalho sujo para mim. Preciso de um compilador? Ok, aperte-o no package.json, faça a instalação do npm, execute tsc e ... nada. Ah, você precisa instalá-lo ainda globalmente? Omitindo os detalhes sem graça da minha guerra com tudo isso, direi que algum tempo depois aprendi a transformar main.ts em main.js. Mas à minha frente estava agitado com o webpack.


Sim, agora percebo que era possível ficar sem ele. Mas quando nas mãos desajeitadas do Typescript, tudo ao redor parece um angular-cli. Já é após a implementação do webpack que soube que o próprio compilador TypeScript é capaz de "monitorar" as alterações nos arquivos, que o problema de importação / exportação pode ser resolvido sem o webpack.


Superação


Após cerca de uma semana, consegui criar um projeto no qual escrevi o código TypeScript, cliquei em "Salvar" e tudo acabou como deveria - o webpack recompilou automaticamente todos os meus arquivos em um único pacote, executando primeiro o compilador TypeScript neles e, em seguida, inserindo o build uma pasta separada onde eu copiei outras coisas estáticas e no navegador naquele momento o lite-server recarregou a página. Eu disse que tudo aconteceu automaticamente? Não, tudo aconteceu automaticamente . Joy não tinha limites, e me sentei para escrever um simples jogo de tiro em arena.


Onde começa pátria é o jogo para mim? Claro, com coisas básicas, como vetores e matrizes matemáticas. Eu superei com sucesso a síndrome de Not Invented Here no trabalho, mas em um hobby não desapareceu. Como não queria bibliotecas prontas, sentei-me para escrever minhas contas. Não, isso é dito em voz alta. Abri minha estrutura anterior do FreePascal ( https://github.com/perfectdaemon/tiny-glr/ ) e comecei a converter matemática a partir daí.


Olhando para o futuro, direi que, em geral, toda a minha nova estrutura é a conversão da antiga do Free Pascal para o TypeScript. Dado mais de um hiato de três anos no desenvolvimento de jogos, eu não conseguia criar uma arquitetura melhor, nem me lembro quais eram as desvantagens do passado.


Depois de algum tempo, comecei a ficar sem fôlego: a motivação naturalmente diminuiu, a carga de trabalho aumentou. E então no igdc anunciou outro concurso. E acredite, a competição é um excelente motivador externo que estabelece limites temáticos, técnicos e de tempo.


Concorrência


Eu já disse no meu último artigo o que é insanidade igdc , mas vou repetir brevemente aqui: é uma comunidade calorosa e acolhedora que realiza concursos de curta ou média duração para desenvolver jogos sobre um determinado tópico. Sem prêmios em dinheiro, patrocinadores renomados e garantias de segurança no emprego. Ah, sim, mesmo sem publicidade, entusiasmo e com o envolvimento de uma doação voluntária para hospedagem e domínio. E assim por quase 15 anos.


Tema da competição - jogo do lixo . Dado um pacote extenso e diversificado de recursos gráficos. A tarefa dos participantes é fazer o jogo usando apenas ele. O gênero e o tema não são limitados, o uso de quaisquer sons e músicas é permitido, uma vez que apenas os gráficos estão no pacote. Há uma limitação técnica histórica associada ao lançamento estritamente offline, sem instaladores, downloads e muito mais.


O último é um pequeno problema, pois o Chrome e a empresa proíbem muitas coisas quando um usuário abre um arquivo html localmente. O WebGL pode não ser ativado, os scripts não desejam ser extraídos, sem mencionar os recursos gráficos. Existe uma saída: criamos um servidor Web super pequeno local e um script de inicialização para o usuário que o buscará e abrirá o navegador favorito do usuário no endereço desejado.


A tarefa é simples: entrei em um exe de 6 kilobytes em C # e um apelido de morcego nas proximidades, que define a pasta raiz do servidor e da porta.


Mas, basta esse pequeno obstáculo a um objetivo grande e limpo - escrever um jogo para a competição.


Jogo de competição


Analisando os recursos, percebi que o atirador de arena com o uso deles seria bastante sólido.


Depois de concluir as coisas básicas, procedi à seleção dos recursos necessários. A fatia final na forma de um atlas de textura é assim:



A propósito, algumas coisas assadas no atlas nunca foram usadas no jogo. Depois de carregar os recursos, iniciei uma nova funcionalidade para mim - animação em sprite. Eu era feliz quando criança quando tudo acabou:



Física própria


Conectar a física de outras pessoas ao desejo desenfreado de inventar a minha própria parecia pelo menos uma blasfêmia e, ao que me parece, nem sequer foi considerado pelo meu organismo entusiasmado (acabei de derrotar a animação de sprites, lembra?). Além disso, o que pode ser difícil no processamento simples de colisões com base em retângulos (caixa delimitadora alinhada ao eixo, AABB) e círculos? Muitas coisas. Começando com um personagem preso em cantos invisíveis e terminando com o fato de você trazer todos os objetos do seu mundo para retângulos e círculos.


Não foi possível resolver todos os problemas, mas apareceu uma certa física:



Sons


Discretamente, esperava que fosse difícil. De fato, acabou de alguma forma suspeitamente simples e eficiente. Criamos um contexto de áudio, criamos um buffer de áudio, colocamos músicas / sons em qualquer formato aceitável para o navegador (usei wav), criamos um nó e dissemos de qual buffer reproduzir.


Os sons que eu gerei usando o bfxr ( https://www.bfxr.net/ ).


Cáqui


Muletas, decisões ad hoc, podhachivaniya - é difícil encontrar uma pessoa que conhece essas palavras apenas por boatos. No final do concurso, inseri alguns backups notáveis.


Não houve saída de texto - html usado


No final da competição, ficou claro que eu não teria tempo para transferir a renderização do texto para o mecanismo. Mesmo sem um gerador. Havia muitas opções, aqui estão quatro principais:


  1. Renderização de texto em uma tela 2D transparente que fica na parte superior da tela com o WebGL.
  2. Faça um jogo sem texto
  3. Asse as palavras necessárias e use-as como sprites
  4. HUD de saída em html

De acordo com os termos da competição, era possível usar apenas a fonte de pixel personalizada fornecida, então a primeira opção (renderizar texto em uma tela 2D) foi descartada. A tela pode ser renderizada usando apenas fontes do sistema. As fontes carregadas no css via fontface funcionam extremamente instáveis.


Tocar sem texto é uma ótima e criativa opção. É uma pena que, com criatividade, naquele momento eu já estivesse me sentindo mal.


O vocabulário mínimo necessário era grande e aumentava o tamanho dos ativos. Além disso, a exibição de números ainda exigia uma certa lógica.


E, finalmente, chegamos à muleta real, que eu usei - eu apenas implementei o HUD como marcação html sob a tela, conectei @fontface ao css e organizei a atualização através da API DOM padrão (getElementById).


Reinício do jogo - document.location.reload ()


Quando um jogador morre, ele quer fechar o jogo ou iniciá-lo novamente. Infelizmente, se você não prever algum mecanismo de reinicialização desde o início e borrar todo o estado do jogo em várias classes mal organizadas, não terá uma reinicialização agradável. Sempre haverá um lugar mágico que não foi zerado.


Uma muleta excelente nesse caso foi o recarregamento de uma página banal através do cabeçalho document.location.reload () mencionado no cabeçalho. Dado o tamanho pequeno da compilação final (menos de 300 kb, incluindo todos os recursos) e o fato de o jogo funcionar localmente, a velocidade de reinicialização pode ser negligenciada.


O que aconteceu



Você pode testá-lo online aqui: https://perfectdaemon.imtqy.com/151/index.html
Link para o repositório: https://github.com/perfectdaemon/ts-game
A versão do repositório com o código-fonte deste jogo: https://github.com/perfectdaemon/ts-game/releases/tag/0.1.0


A conclusão é um final agradável.


Concluindo, gostaria de descrever brevemente os prós e contras subjetivos de escrever jogos no WebGL + TypeScript.


Prós


  • Escreva uma vez, reproduza / depure em qualquer lugar. É muito legal eu poder colocar o jogo no imtqy.com, e qualquer um pode jogá-lo em qualquer dispositivo com um navegador. Naturalmente, com várias reservas.
  • Após certas configurações e adicionar o TypeScript, trabalhar com JS moderno não é tão ruim.
  • Conveniente para criar contexto (em comparação com API Win e OpenGL)
  • Existe uma ferramenta conveniente (Visual Studio Code), que está bem equipada com plug-ins e realmente ajuda a escrever código por meio de dicas, trechos e notas sobre áreas problemáticas.

Contras


  • Javascript é executado em um único segmento. E o problema não é que você queira considerar física ou lógica em fluxos separados. A criação de perfil mostrou que as chamadas WebGL estão bloqueando, ou seja, eles esperam que o controle retorne do driver da placa de vídeo antes de continuar com a execução do código. Embora a maioria das chamadas WebGL retorne nada além de nulo. As implementações de desktop OpenGL (em alguns drivers) para muitas funções retornam o controle instantaneamente, o que aumenta significativamente a velocidade de renderização.
  • Um pequeno passo para a esquerda / direita - e você está completamente sozinho. Está tendo um problema com Angular e Typcript? Os dois primeiros links para sobrecarregar a pilha o ajudarão. Havia um desejo de fazer amizade com o Typecript separadamente e surgiu um bug / pergunta estranha? Prepare-se para o fato de que você pode estar sozinho. Obviamente, como uma pessoa que escreveu anteriormente na muito popular (no) pilha do FreePascal + OpenGL, estou acostumada. Mas no caso de uma linguagem madura como C ++, sempre haverá um indiano que já resolveu esse problema. E então os chineses, que resolveram o problema usando o controle do Guitar Hero e do Arduino.

Source: https://habr.com/ru/post/pt479918/


All Articles