Dobre rozwiązania technologiczne do budowy mapy ascii i poruszania postaciami w przeglądarce (np. Forteca karłowata)? [Zamknięte]

10

Chciałbym zbudować aplikację internetową dla mojej witryny z grami, która polega na użyciu znaków tekstowych do reprezentowania zwierząt i ludzi oraz umożliwienia im poruszania się po polach mapy z niezależną (sterowaną przez serwer) sztuczną inteligencją.

Zasadniczo mapa przeglądarki krasnoludów w przeglądarce: przykład twierdzy krasnoludów z poruszającymi się stworzeniami, mobami, NPC i szt. Chociaż nie dlatego, że nie zamierzam osiągnąć tej skali, prawdopodobnie zacznę pokazywać jedną czwartą takich treści w dowolnym momencie.

Prawdopodobnie niektóre płytki tła / nieruchome można załadować statycznie. Ale w przypadku stworzeń / zwierząt i rzeczy, które mogą się poruszać, nie jestem pewien, jakie rozwiązania technologiczne byłyby najbardziej skuteczne.

Wiem o tym, <canvas>choć nie wiem, czy jego możliwości pasują do tego przypadku użycia. Z pewnością konieczna będzie pewna ilość javascript.

Czy istnieją biblioteki javascript lub biblioteki canvas, które pasują do tego przypadku użycia? Inna technologia, której nie jestem świadomy? Czy ktoś zna jakieś przykłady stron internetowych, które zrobiły coś podobnego do tego, żebym mógł wyciągać z nich pomysły?

Kzqai
źródło
1
Spójrz na rot.js ondras.github.com/rot.js/hp
Alayric
Cóż, rot.js może być dokładnie tym, czego szukałem, ale nie wiedziałem o tym.
Kzqai

Odpowiedzi:

5

Stworzyłem bibliotekę wyświetlania znaków dla sieci, Unicodetiles.js , którą nie tylko spędziłem trochę czasu na optymalizacji, ale także bada ona różne sposoby prezentacji tekstu; ma trzy renderery:

  1. DOM, który wykorzystuje macierz <div>elementów do renderowania każdego glifu z dostosowywanymi kolorami pierwszego planu i tła.
  2. Płótno, które rysuje postacie za pomocą <canvas>elementu. Jest to znacznie szybsze, a istnieją kopie zapasowe testów wydajności: http://tapiov.net/unicodetiles.js/tests/
  3. WebGL, który używa elementu canvas do tworzenia tekstury czcionki, a następnie renderuje przy użyciu WebGL, który jest jeszcze szybszy i bardzo skalowalny do dużych rozmiarów rzutni, ale nie jest tak dobrze obsługiwany w przeglądarkach.

Pamiętaj, że połączone testy wydajności mogą być dość ekstremalne, zmieniając każdą postać w każdej klatce. W praktyce nawet renderer DOM jest wystarczająco szybki do większości celów.

Jeśli zdecydujesz się stworzyć własną bibliotekę, nadal polecam użycie płótna, ponieważ wydaje się, że działa lepiej, pozwalając na większe sceny. Używanie tylko WebGL ograniczy bazę użytkowników i jego wdrożenie jest skomplikowane (Unicodetiles ma automatyczny mechanizm zastępczy).


Inna biblioteka, który Słyszałem niedawno zasugerował dużo jest rot.js . Jest specjalnie ukierunkowany na roguelike, ponieważ ma np. System FOV i generatory lochów. Jeśli potrzebujesz kompletnego pakietu, może to być właściwy sposób.

Tapio
źródło
Miły. Mogę tego użyć. Albo przynajmniej ucz się ze sposobu, w jaki ktoś to zrobił, aby poinformować o moim podejściu, ponieważ chcę zrobić roguelike, ale nie tak jak roguelike. : D
Kzqai,
@Tapio Próbuję wdrożyć Pacmana z Unicodetiles, problem polega na tym, że gracz zawsze jest wyśrodkowany na mapie, jest to niepożądane dla Pacmana, czy mogę go w jakiś sposób wyłączyć lub mogę się poruszać bez określania gracza.
user3995789,
6

Myślę, że najskuteczniejszym sposobem byłoby po prostu sfałszowanie go. Renderowanie do jakiegoś elementu docelowego za pomocą własnej wbudowanej czcionki sprite, tak jakbyś renderował normalny ekran 2D. Takie podejście zapewnia, że ​​nie zdarzają się dziwne rzeczy, gdy ludzie nie mają czcionek lub używają zupełnie innego języka (chiński, rosyjski).

Czcionki i teksty są jedną z najtrudniejszych rzeczy, aby uzyskać idealny piksel we wszystkich lokalizacjach we wszystkich przeglądarkach. Nawet podczas osadzania czcionki i korzystania z niektórych magicznych przeglądarek CSS i ustawień użyteczności nadal można ją zastąpić i zmienić. W przypadku normalnych witryn tekst idealny w pikselach nie stanowi problemu, ale w grach takich jak Dwarf Fortress kilka pikseli może prowadzić do wyjątkowo niespójnego widoku. Nawet jeśli nie używasz przeglądarki, ale normalnej aplikacji, występują problemy z renderowaniem tekstu. Więc nawet sama Twierdza Krasnoludów stosuje podejście, które opisałem.

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

Wyświetlacze ekranowe używają nieznacznie zmodyfikowanych znaków strony kodowej 437 w 16 różnych kolorach zaimplementowanych jako mapy bitowe, renderowane w OpenGL

Edycja: ponieważ dostałem kilka komentarzy, nieco rozszerzyłem odpowiedź

Roy T.
źródło
Czy inne języki nie są rozszerzeniami, a nie zamiennikami ASCII? Dlaczego zwykłe witryny zawierające tekst „nie udają”?
Anko
1
Większości problemów z kodowaniem znaków można zapobiec, stosując kodowanie UTF-8.
Philipp
Rosyjski ma inną czcionkę niż ASCII, a chiński jeszcze bardziej się różni. Zwykła strona internetowa dba o estetykę, która obejmuje takie rzeczy, jak glify o zmiennej wielkości, kerning, ładny „przepływ” tekstu itp. Gra podobna do DF dba o regularne umieszczanie liter, czego nie można w wiarygodny sposób zrobić w przeglądarce internetowej.
Liosan
1
@Liosan na pewno może. Wystarczy użyć deklaracji CSS, font-family:monospace;a przeglądarka internetowa użyje domyślnej czcionki Monospace.
Philipp
Nie jestem pewien, jak by to przyniosło korzyść w porównaniu z osadzoną czcionką monospace-css z rodziny? Chodzi mi o to, że wymagałoby to większego renderowania, czy może pozwoliłoby to na bardziej niezawodne rozwiązywanie problemów z odstępami, ale w przypadku osadzonej czcionki css nie miałoby znaczenia, że ​​ludzie pominęliby czcionkę lub używają innego języka? Chyba ograniczyłoby to operacje tylko do zestawu znaków osadzonej czcionki internetowej, hmmm.
Kzqai,
3

Aby dowiedzieć się, ile wierszy i kolumn chcesz wydrukować, powinieneś sprawdzić szerokość i wysokość okna i odpowiednio je zmienić. Pamiętaj, aby słuchać zdarzeń onResize i odpowiednio modyfikować szerokość i wysokość.

Jeśli chcesz to zrobić tekstowo , możesz to zrobić za pomocą tekstu z czcionką o stałej szerokości i tabelą, w której każda komórka zawiera jeden znak.

Aby adresować poszczególne znaki, możesz utworzyć <table>z odpowiednią liczbą wierszy i kolumn, z których każdy <td>ma identyfikator składający się ze współrzędnych xi y. W ten sposób możesz adresować poszczególne komórki według ID i zmieniać ich innerHTML, aby zmienić literę i zmienić ich klasę css, aby zmienić ich kolor.

Korzystanie z obszaru roboczego może być jednak szybsze, ponieważ nie trzeba manipulować dużym drzewem DOM dla każdego znaku, który należy zastąpić. Nawiasem mówiąc, Dwarf Fortress robi podobne rzeczy. Znaki używane do reprezentowania obiektów są w rzeczywistości bitmapami, a nie prawdziwym tekstem wyjściowym i są rysowane przy użyciu graficznych interfejsów API 2d. Płótno HTML5 jest do tego dobrze przygotowane. Ma metodę context.fillText , która pozwala rysować tekst na płótnie. Można to wykorzystać do rysowania pojedynczych postaci. Możesz zmienić rozmiar i czcionkę, manipulując zmiennymi context.font i kolorem każdej litery, wywołując kontekst.fillStyle .

Pamiętaj, że wywoływanie fillText setki razy na ramkę może być powolne, ponieważ rasteryzacja czcionek jest droga i żadna przeglądarka, o której wiem, nie używa buforowania. Oznacza to, że jeśli wyrenderujesz tę samą literę z tymi samymi ustawieniami sto razy, zostanie ona ponownie zrasteryzowana sto razy. Aby zwiększyć wydajność, możesz buforować zrasteryzowany wygląd każdej litery z każdym kolorem na ukrytym płótnie, a następnie narysować te ukryte płótna za pomocą kontekstu.drawImage . Kopiowanie z jednego obszaru roboczego na drugi jest zwykle znacznie szybsze niż rasteryzacja czcionek.

Obecnie opracowuję grę 2D przy użyciu płótna i zauważyłem, że największym zjadaczem FPS był rysunek czcionek. Kiedy dodałem pamięć podręczną zrasteryzowanego tekstu, znacznie poprawiło to wydajność.

Philipp
źródło
Czcionki bitmapowe są również prawdziwym tekstem! Cały czas używam ich w terminalu. Ponadto, jeśli płótno jest szybsze, dlaczego StackExchange nie renderuje tekstu w oparciu o płótno?
Anko
cholera, teraz chcę dla tego napisać bibliotekę.
Philipp
@Anko terminal! = Przeglądarka internetowa. Do jakiego renderowania tekstu chodzi dokładnie?
Philipp
1
Anko mówi, że ponieważ czcionki bitmapowe są prawdziwym tekstem, może ich używać w swoim terminalu - i to jest jego dowód na to, że czcionki bitmapowe są prawdziwym tekstem.
Polar
0

OK, to tylko dźgnięcie w ciemność i nie wiem, jak to się robi.

Zasadniczo korzystasz z tych samych konsol tricków (zwanych też terminalami), co w dawnych czasach. Najpierw zacznij od czcionki Monospace. Masz M linii z N znakami. Więc po prostu zrzuć tekst na div, który jest wystarczająco szeroki (szerokość: N em?) I umieść co N znaków w podziale linii; w tym przypadku <br/>zamiast zamiast \n.

Sztuczka polega na zastąpieniu bufora char albo char lub całej zawartości jednocześnie skryptem Java.

Jeśli chcesz być naprawdę konkretny, możesz użyć @ font-face, aby upewnić się, że wszędzie masz tę samą czcionkę o stałej szerokości.

Rioki
źródło
Zastanawiałem się nad tym, ale zdałem sobie sprawę, że nie będzie to dobra architektura, jeśli chcesz kontrolować kolor i kolor tła każdej postaci.
Philipp
0

Myśl w kategoriach glifów. Oddziel wyświetlanie tekstu od jego znaczenia. Na przykład:

(pseudo kod)

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

display(glyph);

A następnie w swoim podstawowym kodzie definiującym atlas glifów, po prostu zrób coś takiego:

Glyph.Asterisk = "*";

Atlas glifów może być w rzeczywistości przeglądaniem tabeli ascii z różnymi kodowaniami. Chodzi tutaj jedynie o to, aby oddzielić, kiedy wyświetlać, od tego, co ma zostać wyświetlone. Poleciłbym stworzenie frameworka od zera. Dałoby ci to więcej swobody.

Jason Coombes
źródło