De bonnes solutions technologiques pour construire une carte ascii et déplacer des personnages dans un navigateur (comme une forteresse naine)? [fermé]

10

Je voudrais créer une application Web pour mon site Web de jeu qui implique l'utilisation de caractères texte pour représenter les animaux et les personnes, et les faire se déplacer sur des carrés de carte avec une IA indépendante (pilotée par le serveur).

Donc, essentiellement, une carte de forteresse naine dans le navigateur: exemple-forteresse naine avec des créatures en mouvement, des foules, des PNJ et des PC. Bien que je ne cherche pas à atteindre cette échelle, je commencerais probablement à montrer un quart de ce contenu à tout moment.

Probablement certaines des tuiles d'arrière-plan / immobiles pourraient être chargées statiquement. Mais pour les créatures / animaux et les choses qui peuvent bouger, je ne sais pas quelles solutions technologiques seraient les plus efficaces.

Je <canvas>sais que je ne sais pas si ses capacités conviennent à ce cas d'utilisation. Une certaine quantité de javascript va certainement être nécessaire.

Existe-t-il des bibliothèques javascript ou des bibliothèques de canevas adaptées à ce cas d'utilisation? Une autre technologie que je ne connais pas? Quelqu'un connaît-il des exemples de sites Web qui ont fait quelque chose de similaire à cela, de sorte que je puisse leur proposer des idées?

Kzqai
la source
1
Jetez un œil à rot.js ondras.github.com/rot.js/hp
Alayric
Eh bien, rot.js est peut-être exactement ce que je cherchais, mais je ne le savais pas.
Kzqai

Réponses:

5

J'ai en fait créé une bibliothèque d'affichage de caractères pour le Web, Unicodetiles.js , que j'ai non seulement passé un peu de temps à optimiser, mais qui explore également différentes façons de présenter le texte; il a trois moteurs de rendu:

  1. DOM, qui utilise une matrice d' <div>éléments pour rendre chaque glyphe avec des couleurs d'avant-plan et d'arrière-plan personnalisables.
  2. Canvas, qui dessine les personnages en utilisant l' <canvas>élément. C'est beaucoup plus rapide, et il existe des tests de performances pour le confirmer : http://tapiov.net/unicodetiles.js/tests/
  3. WebGL, qui utilise un élément canvas pour créer une texture de police, puis effectue un rendu à l'aide de WebGL, qui est encore plus rapide et très évolutif pour les grandes tailles de fenêtres, mais pas aussi bien pris en charge dans les navigateurs.

Notez que les tests de performances liés peuvent être assez extrêmes, changeant chaque caractère à chaque image. En pratique, même le rendu DOM est suffisamment rapide pour la plupart des applications.

Si vous décidez de créer votre propre bibliothèque, je recommanderais toujours d'utiliser le canevas car il semble mieux fonctionner, permettant des scènes plus grandes. L'utilisation de WebGL uniquement limitera la base d'utilisateurs et sa mise en œuvre est complexe (Unicodetiles possède un mécanisme de secours automatique).


Une autre bibliothèque, que je l' ai suggéré entendu beaucoup est récemment rot.js . Il est spécialement conçu pour les roguelikes car il est fourni avec, par exemple, un système FOV et des générateurs de donjon. Si vous voulez un package complet, c'est peut-être la voie à suivre.

Tapio
la source
Agréable. Je peux l'utiliser. Ou du moins apprendre de la façon dont quelqu'un d'autre l'a fait pour informer ma propre approche, car je veux faire un roguelike, mais pas comme un roguelike. : D
Kzqai
@Tapio J'essaie d'implémenter pacman avec des unicodétiles, le problème est que le joueur est toujours centré sur la carte, ce n'est pas souhaitable pour pacman, puis-je le désactiver d'une manière ou d'une autre sans spécifier le joueur.
user3995789
6

Je pense que le moyen le plus efficace serait de le simuler. Rendu à un élément cible à l'aide de votre propre police d'image-objet intégrée comme si vous rendiez un écran 2D normal. Cette approche garantit qu'aucune chose étrange ne se produit lorsque les gens manquent de polices ou utilisent une langue très différente (chinois, russe).

Les polices et les textes sont l'une des choses les plus difficiles à obtenir en pixels parfaits dans tous les paramètres régionaux sur tous les navigateurs. Même lorsque vous incorporez une police et utilisez un navigateur magique CSS et que les paramètres d'utilisabilité peuvent toujours remplacer et modifier. Pour les sites Web normaux, le texte parfait en pixels n'est pas un problème, mais dans des jeux comme Dwarf Fortress, quelques pixels peuvent conduire à une vue extrêmement incohérente. Même si vous n'utilisez pas de navigateur mais une application normale, il y a des problèmes avec le rendu du texte. Ainsi, même Dwarf Fortress lui-même utilise l'approche que j'ai décrite.

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

Les affichages à l'écran utilisent des codes de page de code légèrement modifiés 437 dans 16 couleurs différentes implémentées sous forme de bitmaps, rendus avec OpenGL

Edit: parce que j'ai eu quelques commentaires, j'ai étendu un peu la réponse

Roy T.
la source
D'autres langues ne sont-elles pas des extensions plutôt que des remplacements d'ASCII? Pourquoi les sites Web habituels contenant du texte ne font-ils pas semblant?
Anko
1
La plupart des problèmes de codage de caractères peuvent être évités en utilisant le codage UTF-8.
Philipp
Le russe a une police différente de l'ASCII et le chinois est encore plus différent. Le site Web se soucie généralement de l'esthétique, qui comprend des éléments tels que des glyphes de taille variable, le crénage, un "flux" de texte agréable, etc. Un jeu de type DF se soucierait du placement régulier des lettres, ce qui ne peut pas être fait de manière fiable dans un navigateur Web.
Liosan
1
@Liosan bien sûr. Utilisez simplement la déclaration CSS font-family:monospace;et le navigateur Web utilisera la police monospace par défaut.
Philipp
Je ne sais pas vraiment en quoi cela serait avantageux par rapport à une police Web intégrée de la famille monospace CSS? Je veux dire, cela prendrait plus de rendu, peut-être que cela permettrait de résoudre les problèmes d'espacement de manière plus fiable, mais avec une police CSS intégrée, cela n'aurait pas d'importance si les gens manquaient la police ou utilisaient une langue différente? Bien que je suppose que cela limiterait les opérations au jeu de caractères de la police Web intégrée, hmmm.
Kzqai
3

Pour connaître le nombre de lignes et de colonnes à afficher, vous devez vérifier la largeur et la hauteur de la fenêtre et les modifier en conséquence. N'oubliez pas d'écouter les événements onResize et de modifier la largeur et la hauteur en conséquence.

Lorsque vous souhaitez effectuer cette opération de manière textuelle , vous pouvez le faire en utilisant du texte avec une police à espacement fixe et un tableau dans lequel chaque cellule contient un caractère.

Pour adresser des caractères individuels, vous pouvez créer un <table>avec le nombre correct de lignes et de colonnes, où chacun <td>a un ID composé de ses coordonnées x et y. De cette façon, vous pouvez adresser des cellules individuelles par ID et changer leur innerHTML pour changer la lettre et changer leur classe css pour changer leur couleur.

Cependant, l' utilisation d'un canevas peut être plus rapide car vous n'avez pas à manipuler une grande arborescence DOM pour chaque caractère que vous devez remplacer. Soit dit en passant, la forteresse naine fait la même chose. Les caractères qui sont utilisés pour représenter des objets sont en fait des bitmaps, et non de la véritable sortie de texte, et ils sont dessinés à l'aide d'API graphiques 2D. Le canevas HTML5 est bien équipé pour cela. Il a la méthode context.fillText qui vous permet de dessiner du texte sur la toile. Cela peut être utilisé pour dessiner des caractères individuels. Vous pouvez changer la taille et la police en manipulant les variables context.font et la couleur de chaque lettre en appelant context.fillStyle .

Notez que l'appel de fillText des centaines de fois par image peut être lent, car la pixellisation des polices est coûteuse et aucun navigateur que je connais n'utilise la mise en cache. Cela signifie que lorsque vous restituez cent fois la même lettre avec les mêmes paramètres, elle sera re-pixellisée cent fois. Pour augmenter les performances, vous pouvez mettre en cache l'apparence tramée de chaque lettre avec chaque couleur sur un canevas masqué, puis dessiner ces toiles masquées à l'aide de context.drawImage . La copie d'un canevas à un autre est généralement beaucoup plus rapide que la pixellisation des polices.

Je suis en train de développer un jeu 2D en utilisant la toile et j'ai remarqué que le plus gros mangeur de FPS était le dessin des polices. Lorsque j'ai ajouté un cache pour le texte tramé, cela a beaucoup amélioré les performances.

Philipp
la source
Les polices bitmap sont également de véritables sorties de texte! Je les utilise dans un terminal tout le temps. De plus, si un canevas est plus rapide, pourquoi le rendu de texte de StackExchange n'est-il pas basé sur le canevas?
Anko
putain, maintenant je veux écrire une bibliothèque pour ça.
Philipp
@Anko terminal! = Navigateur Web. De quel rendu de texte parlez-vous exactement?
Philipp
1
Anko dit que les polices bitmap étant du texte vrai, il peut les utiliser dans son terminal - et c'est ainsi sa preuve que les polices bitmap sont du texte vrai.
Polar
0

OK, c'est juste un coup de couteau dans le noir et je ne sais pas comment ça se passe.

Fondamentalement, vous utilisez les mêmes consoles astuces (aka terminal) utilisées dans les temps anciens. Commencez d'abord par une police à espacement fixe. Vous avez M lignes avec N caractères. Il vous suffit donc de vider le texte dans un div suffisamment large (largeur: N em?) Et de mettre tous les N caractères un saut de ligne; dans ce cas, un <br/>au lieu d'un \n.

L'astuce consiste à remplacer le tampon, soit char par char, soit l'ensemble du contenu à la fois par un script java.

Si vous voulez être vraiment précis, vous pouvez utiliser @ font-face pour vous assurer d'avoir la même police monospace partout.

rioki
la source
J'ai aussi pensé à faire ça, mais j'ai réalisé que ce ne serait pas une bonne architecture quand on veut contrôler la couleur et la couleur de fond de chaque personnage individuel.
Philipp
0

Pensez en termes de glyphes. Découplez l'affichage du texte de sa signification. Par exemple:

(pseudo code)

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

display(glyph);

Et puis dans votre code sous-jacent pour définir l'atlas des glyphes, faites simplement quelque chose comme:

Glyph.Asterisk = "*";

L'atlas des glyphes peut en fait être une recherche dans une table ascii avec différents encodages. Le point ici est simplement de séparer quand afficher, avec ce qui doit être affiché. Je recommanderais de créer un cadre à partir de zéro. Cela vous donnerait plus de liberté.

Jason Coombes
la source