Buone soluzioni tecnologiche per costruire una mappa ASCII e spostare i personaggi in un browser (come la fortezza nana)? [chiuso]


10

Mi piacerebbe creare una webapp per il mio sito Web di gioco che implichi l'uso di caratteri di testo per rappresentare animali e persone e farli muovere sulle piazze della mappa con un'IA indipendente (guidata dal server).

Quindi, essenzialmente, una mappa di fortezza nana nel browser: nana-fortezza-example con creature in movimento, mob, npc e pc. Anche se non sto cercando di raggiungere questa scala, probabilmente inizierei a mostrare un quarto di questo contenuto in qualsiasi momento.

Probabilmente alcune tessere di sfondo / immobili potrebbero essere caricate staticamente. Ma per le creature / animali e le cose che possono muoversi, non sono sicuro di quali soluzioni tecnologiche sarebbero più efficaci.

Sono a conoscenza <canvas>anche se non so se le sue capacità si adattano a questo caso d'uso. Certamente sarà necessaria una certa quantità di javascript.

Esistono librerie javascript o librerie canvas adatte a questo caso d'uso? Un'altra tecnologia di cui non sono a conoscenza? Qualcuno sa di alcuni esempi di siti Web che hanno fatto qualcosa di simile a questo, in modo da poter cogliere idee da loro?


1
Dai un'occhiata a rot.js ondras.github.com/rot.js/hp
Alayric,

Bene, rot.js potrebbe essere esattamente quello che stavo cercando, ma non lo sapevo.
Kzqai,

Risposte:


5

In realtà ho creato una libreria di visualizzazione dei caratteri per il web, Unicodetiles.js , che non solo ho trascorso un po 'di tempo a ottimizzare, ma esplora anche diversi modi di presentare il testo; ha tre renderer:

  1. DOM, che utilizza una matrice di <div>elementi per rendere ogni glifo con un primo piano personalizzabile e colori di sfondo.
  2. Canvas, che disegna i personaggi usando l' <canvas>elemento. Questo è molto più veloce e ci sono test delle prestazioni per il backup: http://tapiov.net/unicodetiles.js/tests/
  3. WebGL, che utilizza un elemento canvas per creare una trama del carattere e quindi esegue il rendering utilizzando WebGL, che è ancora più veloce e molto scalabile per dimensioni di finestre grandi, ma non altrettanto supportato nei browser.

Nota che i test delle prestazioni collegati possono essere piuttosto estremi, cambiando ogni personaggio in ogni frame. In pratica, anche il renderer DOM è abbastanza veloce per la maggior parte degli scopi.

Se decidi di creare la tua libreria, ti consiglierei comunque di usare canvas perché sembra funzionare meglio, consentendo scene più grandi. L'uso di solo WebGL limiterà la base di utenti ed è complesso da implementare (Unicodetiles ha un meccanismo di fallback automatico).


Un'altra libreria, che ho sentito suggerito un sacco di recente è rot.js . È specificamente orientato ai roguelike in quanto viene fornito ad esempio con il sistema FOV e generatori di sotterranei. Se si desidera un pacchetto completo, questa potrebbe essere la strada da percorrere.


Bello. Posso usarlo. O almeno impara dal modo in cui qualcun altro ha fatto per informare il mio approccio, dal momento che voglio fare un roguelike, ma non così come un roguelike. : D
Kzqai,

@Tapio Sto cercando di implementare pacman con unicodetiles, il problema è che il giocatore è sempre centrato nella mappa, è indesiderabile per pacman, posso disabilitarlo in qualche modo o posso spostarmi senza specificare il giocatore.
user3995789

6

Penso che il modo più efficace sarebbe solo fingere. Esegui il rendering su alcuni elementi target usando il tuo font sprite incorporato come se stessi riproducendo uno schermo 2D normale. Questo approccio assicura che non succeda nulla di strano quando le persone mancano di caratteri o usano una lingua molto diversa (cinese, russo).

Caratteri e testi sono una delle cose più difficili da ottenere pixel perfetti in tutte le versioni locali su tutti i browser. Anche quando si incorpora un font e si utilizza un browser magico CSS e le impostazioni di usabilità possono comunque sostituirlo e modificarlo. Per i normali siti Web il testo perfetto per i pixel non è un problema, ma in giochi come Dwarf Fortress alcuni pixel possono portare a una visione estremamente incoerente. Anche quando non si utilizza un browser ma un'applicazione normale ci sono problemi con il rendering del testo. Quindi anche la fortezza nana stessa utilizza l'approccio che ho descritto.

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

I display su schermo utilizzano 437 caratteri di tabella codici leggermente modificati in 16 colori diversi implementati come bitmap, resi con OpenGL

Modifica: poiché ho ricevuto alcuni commenti ho esteso un po 'la risposta


Altre lingue non sono estensioni anziché sostituzioni di ASCII? Perché i soliti siti Web contenenti testo non "fingono"?
Anko,

1
La maggior parte dei problemi di codifica dei caratteri può essere prevenuta utilizzando la codifica UTF-8.
Philipp

Il russo ha un carattere diverso da ASCII e il cinese è ancora più diverso. Il solito sito web si preoccupa dell'estetica, che include elementi come glifi di dimensioni variabili, crenatura, un bel "flusso" di testo, ecc. Un gioco simile a DF si preoccuperebbe del posizionamento regolare delle lettere, che non può essere fatto in modo affidabile in un browser web.
Liosan,

1
@Liosan certo che può. Basta usare la dichiarazione CSS font-family:monospace;e il browser web utilizzerà il carattere monospace predefinito.
Philipp

In realtà non sono sicuro di come questo sarebbe di beneficio rispetto a un font web monospace della famiglia css incorporato? Voglio dire, ci vorrebbe più rendering, ma consentirebbe di risolvere i problemi di spaziatura in modo più affidabile, ma con un font css incorporato non importa se alla gente manca il font o usa una lingua diversa? Anche se immagino che ciò limiterebbe le operazioni al solo set di caratteri del carattere web incorporato, hmmm.
Kzqai,

3

Per scoprire il numero di linee e colonne che devi produrre, dovresti controllare la larghezza e l'altezza della finestra e cambiarla di conseguenza. Ricorda di ascoltare gli eventi onResize e modificare la larghezza e l'altezza di conseguenza.

Quando vuoi farlo nel modo testuale , puoi farlo usando il testo con un carattere a spaziatura singola e una tabella in cui ogni cella contiene un carattere.

Per indirizzare i singoli caratteri è possibile creare un <table>con il numero corretto di righe e colonne, in cui ognuna <td>ha un ID costituito dalle sue coordinate x e y. In questo modo puoi indirizzare le singole celle per ID e cambiare il loro HTML interno per cambiare la lettera e cambiare la loro classe css per cambiare il loro colore.

L'uso di una tela , tuttavia, potrebbe essere più veloce perché non devi manipolare un grande albero DOM per ogni personaggio che devi sostituire. A proposito, la fortezza nana sta facendo una cosa simile. I caratteri utilizzati per rappresentare gli oggetti sono in realtà bitmap, non veri output di testo e sono disegnati utilizzando API grafiche 2D. La tela HTML5 è ben equipaggiata per questo. Ha il metodo context.fillText che ti permette di disegnare del testo sulla tela. Questo può essere usato per disegnare singoli personaggi. È possibile modificare la dimensione e la faccia del carattere manipolando le variabili context.font e il colore di ogni lettera chiamando context.fillStyle .

Si noti che la chiamata a fillText centinaia di volte per frame potrebbe essere lenta, poiché la rasterizzazione dei caratteri è costosa e nessun browser che conosco utilizza la memorizzazione nella cache. Ciò significa che quando si rende la stessa lettera con le stesse impostazioni cento volte, verrà rasterizzata cento volte. Per aumentare le prestazioni è possibile memorizzare nella cache l'aspetto rasterizzato di ogni lettera con ogni colore su una tela nascosta e quindi disegnare queste tele nascoste utilizzando context.drawImage . La copia da una tela all'altra è in genere molto più veloce della rasterizzazione dei caratteri.

Attualmente sto sviluppando un gioco 2d usando canvas, e ho notato che il più grande mangiatore di FPS era il disegno dei caratteri. Quando ho aggiunto una cache per il testo rasterizzato, le prestazioni sono migliorate molto.


I caratteri bitmap sono anche output di testo vero! Li uso sempre in un terminale. Inoltre, se un canvas è più veloce, perché StackExchange non è basato sul rendering del testo basato su canvas?
Anko,

accidenti, ora voglio scrivere una libreria per quello.
Philipp

@Anko terminal! = Browser web. A quale rendering del testo ti riferisci esattamente?
Philipp

1
Anko sta dicendo che, poiché i caratteri bitmap sono true-text, può usarli nel suo terminale, e questa è quindi la sua prova che i caratteri bitmap sono true-text.
Polar

0

OK, questa è solo una pugnalata nel buio e non so come sia possibile.

Fondamentalmente si usano le stesse console di trucco (alias terminal) usate ai vecchi tempi. Innanzitutto si inizia con un carattere monospace. Hai M righe con N caratteri. Quindi devi semplicemente scaricare il testo in un div abbastanza largo (larghezza: N em?) E mettere ogni N caratteri in una riga; in questo caso a <br/>anziché a \n.

Il trucco è sostituire il buffer, char con char o l'intero contenuto in una sola volta con java script.

Se vuoi essere veramente specifico, puoi usare @ font-face per assicurarti di avere lo stesso carattere monospace ovunque.


Ho anche pensato di farlo, ma poi ho capito che non sarebbe stata una buona architettura quando si desidera controllare il colore e il colore di sfondo di ogni singolo personaggio.
Philipp

0

Pensa in termini di glifi. Disaccoppia la visualizzazione del testo dal significato che sta dietro. Per esempio:

(pseudo codice)

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

display(glyph);

E poi nel tuo codice sottostante per definire l'atlante glifo, fai semplicemente qualcosa come:

Glyph.Asterisk = "*";

L'atlante glifo può infatti essere una ricerca in una tabella ASCII con varie codifiche. Il punto qui è semplicemente quello di separare quando visualizzare, con ciò che deve essere visualizzato. Consiglierei di creare un framework da zero. Ti darebbe più libertà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.