Boas soluções tecnológicas para construir um mapa ascii e mover personagens em um navegador (como a fortaleza dos anões)? [fechadas]

10

Gostaria de criar um webapp para o site do meu jogo que envolva o uso de caracteres de texto para representar animais e pessoas, e fazer com que eles se movimentem nos quadrados do mapa com IA independente (orientada pelo servidor).

Então, essencialmente, um mapa de fortaleza anã no navegador: anão-fortaleza-exemplo com criaturas em movimento, mobs, npcs e pcs. Embora não que eu não queira alcançar essa escala, provavelmente começaria a mostrar um quarto desse conteúdo a qualquer momento.

Provavelmente, alguns dos blocos de segundo plano / imóveis podem ser carregados estaticamente. Mas para criaturas / animais e coisas que podem se mover, não tenho certeza de quais soluções tecnológicas seriam mais eficazes.

Estou ciente de <canvas>que não sei se seus recursos se encaixam nesse caso de uso. Certamente alguma quantidade de javascript será necessária.

Existem bibliotecas javascript ou canvas disponíveis para esse caso de uso? Outra tecnologia que eu não conheço? Alguém conhece exemplos de sites que fizeram algo parecido com isso, para que eu possa usar idéias deles?

Kzqai
fonte
1
Dê uma olhada em rot.js ondras.github.com/rot.js/hp
Alayric 26/03
Bem, o rot.js pode ser exatamente o que eu estava procurando, mas não sabia disso.
Kzqai #

Respostas:

5

Na verdade, criei uma biblioteca de exibição de caracteres para a Web, Unicodetiles.js , que não só passei algum tempo otimizando, mas também explora diferentes maneiras de apresentar o texto; possui três renderizadores:

  1. DOM, que usa uma matriz de <div>elementos para renderizar cada glifo com cores personalizáveis ​​em primeiro plano e plano de fundo.
  2. Tela, que desenha os caracteres usando o <canvas>elemento Isso é muito mais rápido e há testes de desempenho para fazer o backup: http://tapiov.net/unicodetiles.js/tests/
  3. O WebGL, que usa um elemento canvas para criar uma textura de fonte e depois renderiza usando o WebGL, que é ainda mais rápido e muito escalável para tamanhos de viewport grandes, mas não é tão bem suportado nos navegadores.

Observe que os testes de desempenho vinculados podem ser bastante extremos, alterando cada caractere a cada quadro. Na prática, até o renderizador DOM é rápido o suficiente para a maioria dos propósitos.

Se você decidir criar sua própria biblioteca, eu ainda recomendaria o uso da tela, pois ela parece ter um desempenho melhor, permitindo cenas maiores. Usar apenas WebGL limitará a base de usuários e é complexo de implementar (Unicodetiles possui um mecanismo de fallback automático).


Outra biblioteca, que eu ouvi sugeriu muito recentemente é rot.js . Ele é voltado especificamente para motos roguelike, pois é fornecido com, por exemplo, sistema FOV e geradores de masmorra. Se você deseja um pacote completo, esse pode ser o caminho.

Tapio
fonte
Agradável. Eu posso usar isso. Ou, pelo menos, aprenda com a maneira como alguém fez isso para informar minha própria abordagem, já que eu quero fazer um roguelike, mas não como um roguelike. : D
Kzqai 27/03
@Tapio Estou tentando implementar o pacman com unicodetiles, o problema é o jogador sempre centralizado no mapa, é indesejável para o pacman, posso desabilitá-lo de alguma forma ou posso andar sem especificar o jogador.
user3995789
6

Eu acho que a maneira mais eficaz seria apenas fingir. Renderizando para algum elemento de destino usando sua própria fonte de sprite incorporada, como se estivesse renderizando uma tela 2D normal. Essa abordagem garante que nada de estranho aconteça quando as pessoas não têm fontes ou usam um idioma muito diferente (chinês, russo).

Fontes e textos são uma das coisas mais difíceis de obter pixel perfeito em todos os locais em todos os navegadores. Mesmo ao incorporar uma fonte e usar algum navegador mágico CSS e configurações de usabilidade, ainda é possível substituí-la e alterá-la. Para sites normais, o texto perfeito com pixels não é um problema, mas em jogos como o Dwarf Fortress, alguns pixels podem levar a uma visão extremamente incoerente. Mesmo quando não estiver usando um navegador, mas um aplicativo normal, há problemas com a renderização de texto. Assim, até o próprio Dwarf Fortress usa a abordagem que descrevi.

http://en.wikipedia.org/wiki/Dwarf_Fortress

As exibições na tela usam caracteres da página de código 437 levemente modificados em 16 cores diferentes implementadas como bitmaps, renderizadas com OpenGL

Edit: porque recebi alguns comentários, estendi a resposta um pouco

Roy T.
fonte
Outros idiomas não são extensões e não substituições de ASCII? Por que sites comuns que contêm texto "fingem"?
Anko
1
A maioria dos problemas de codificação de caracteres pode ser evitada usando a codificação UTF-8.
27413 Philipp Philipp
O russo tem uma fonte diferente da ASCII e o chinês é ainda mais diferente. Os sites comuns se preocupam com a estética, que inclui coisas como glifos de tamanho variável, kerning, bom "fluxo" de texto etc. Um jogo semelhante ao DF se preocupa com o posicionamento regular de letras, o que não pode ser feito com segurança em um navegador da web.
Liosan 26/03
1
@ Liosan com certeza pode. Basta usar a declaração CSS font-family:monospace;e o navegador da Web usará a fonte monoespaçada padrão.
Philipp
Na verdade, não tenho certeza de como isso seria benéfico contra uma fonte da Web de família monospace css incorporada? Quero dizer, seria necessário mais renderização, talvez isso permitisse que os problemas de espaçamento fossem resolvidos de maneira mais confiável, mas com uma fonte css incorporada, não importaria se as pessoas sentissem falta da fonte ou usassem um idioma diferente? Embora eu ache que isso restrinja as operações apenas ao conjunto de caracteres da fonte da Web incorporada, hmmm.
Kzqai
3

Para descobrir o número de linhas e colunas que você precisa produzir, verifique a largura e a altura da janela e altere-a de acordo. Lembre-se de ouvir os eventos onResize e modifique a largura e a altura de acordo.

Quando você quiser fazer isso da maneira textual , poderá fazer isso usando texto com uma fonte monoespaçada e uma tabela em que cada célula contenha um caractere.

Para endereçar caracteres individuais, você pode criar um <table>com o número correto de linhas e colunas, onde cada <td>um possui um ID que consiste em suas coordenadas x e y. Dessa forma, você pode endereçar células individuais por ID e alterar seu innerHTML para alterar a letra e alterar sua classe css para alterar sua cor.

O uso de uma tela , no entanto, pode ser mais rápido, porque você não precisa manipular uma grande árvore DOM para cada caractere que precisa substituir. A Fortaleza dos Anões está fazendo uma coisa semelhante, a propósito. Os caracteres usados ​​para representar objetos são, na verdade, bitmaps, não saída de texto verdadeiro, e são desenhados usando APIs gráficas 2D. A tela HTML5 está bem equipada para isso. Possui o método context.fillText que permite desenhar texto na tela. Isso pode ser usado para desenhar caracteres individuais. Você pode alterar o tamanho e a fonte da fonte manipulando as variáveis context.font e a cor de cada letra chamando context.fillStyle .

Observe que a chamada fillText centenas de vezes por quadro pode ser lenta, porque a rasterização das fontes é cara e nenhum navegador que conheço usa cache. Isso significa que, quando você renderizar a mesma letra com as mesmas configurações cem vezes, ela será rasterizada novamente cem vezes. Para aumentar o desempenho, você pode armazenar em cache a aparência rasterizada de cada letra com cada cor em uma tela oculta e desenhá-las usando context.drawImage . Copiar de uma tela para outra geralmente é muito mais rápido que a rasterização de fontes.

Atualmente, estou desenvolvendo um jogo 2D usando canvas e percebi que o maior consumidor de FPS era o desenho da fonte. Quando adicionei um cache para texto rasterizado, ele melhorou muito o desempenho.

Philipp
fonte
Fontes de bitmap também são verdadeiras saídas de texto! Eu os uso em um terminal o tempo todo. Além disso, se uma tela é mais rápida, por que a renderização de texto do StackExchange não é baseada em tela?
Anko 26/03
caramba, agora eu quero escrever uma biblioteca para isso.
26513 Philipp
@Anko terminal! = Navegador da web. A que renderização de texto você se refere exatamente?
27413 Philipp Philipp
1
Anko está dizendo que, como fontes de bitmap são texto verdadeiro, ele pode usá-las em seu terminal - e essa é sua prova de que fontes de bitmap são texto verdadeiro.
Polar
0

OK, isso é apenas uma facada no escuro e eu não sei como isso se processa.

Basicamente, você usa os mesmos consoles de truque (também conhecido como terminal) nos velhos tempos. Primeiro você começa com uma fonte monoespaçada. Você tem M linhas com N caracteres. Então você simplesmente despeja o texto em uma div que seja larga o suficiente (largura: Nem?) E coloca a cada N caracteres uma quebra de linha; neste caso, a em <br/>vez de a \n.

O truque é substituir o buffer, char por char ou todo o conteúdo de uma só vez, com script java.

Se você quiser ser realmente específico, use o @ font-face para garantir que você tenha a mesma fonte monoespaçada em todos os lugares.

rioki
fonte
Também pensei em fazer isso, mas percebi que não seria uma boa arquitetura quando você deseja controlar a cor e a cor de fundo de cada personagem individual.
Philipp
0

Pense em termos de glifos. Separar a exibição do texto do significado por trás dele. Por exemplo:

(pseudo-código)

if (display.hitGlyph)
    glyph = Glyph.Asterisk;

display(glyph);

E então, no seu código subjacente para definir o atlas de glifos, faça algo como:

Glyph.Asterisk = "*";

O atlas de glifos pode de fato ser uma pesquisa em uma tabela ascii com várias codificações. O ponto aqui é apenas separar quando exibir, com o que deve ser exibido. Eu recomendaria fazer uma estrutura a partir do zero. Daria mais liberdade.

Jason Coombes
fonte