Хорошие технологические решения для построения карты ASCII и перемещения персонажей в браузере (например, Dwarf Fortress)? [закрыто]


10

Я хотел бы создать веб-приложение для своего игрового веб-сайта, которое включает в себя использование текстовых символов для представления животных и людей и позволяет им перемещаться по квадратам карты с независимым (управляемым сервером) ИИ.

Итак, по сути, карта карлика-крепости в браузере: карлик-крепость-пример с движущимися существами, мобами, NPC и ПК. Хотя я и не собираюсь достигать этой шкалы, я бы, вероятно, начал показывать четверть контента или около того в любое время.

Вероятно, некоторые фоновые / неподвижные плитки могут быть загружены статически. Но для существ / животных и вещей, которые могут двигаться, я не уверен, какие технологические решения будут наиболее эффективными.

Я знаю, <canvas>хотя я не знаю, соответствуют ли его возможности этому варианту использования. Конечно, некоторое количество javascript будет необходимо.

Существуют ли библиотеки javascript или библиотеки canvas, подходящие для этого варианта использования? Еще одна технология, о которой я не знаю? Кто-нибудь знает какие-либо примеры веб-сайтов, которые делали что-то подобное, чтобы я мог черпать идеи из них?


1
Взгляните на rot.js ondras.github.com/rot.js/hp
Алайрик

Что ж, rot.js может быть именно тем, что я искал, но не знал об этом.
Kzqai

Ответы:


5

На самом деле я создал библиотеку отображения символов для Интернета, Unicodetiles.js , которую я не только потратил некоторое время на оптимизацию, но также исследую различные способы представления текста; у него есть три рендера:

  1. DOM, который использует матрицу <div>элементов для визуализации каждого глифа с настраиваемыми цветами переднего плана и фона.
  2. Холст, который рисует символы с помощью <canvas>элемента. Это намного быстрее, и есть тесты производительности, чтобы подтвердить это: http://tapiov.net/unicodetiles.js/tests/
  3. WebGL, который использует элемент canvas для создания текстуры шрифта, а затем выполняет рендеринг с использованием WebGL, который еще быстрее и очень масштабируем для больших размеров области просмотра, но не так хорошо поддерживается в браузерах.

Обратите внимание, что связанные тесты производительности могут быть довольно экстремальными, меняя каждый символ в каждом кадре. На практике даже DOM-рендеринг достаточно быстр для большинства целей.

Если вы решите создать свою собственную библиотеку, я бы по-прежнему рекомендовал использовать canvas, потому что он, кажется, работает лучше, позволяя создавать большие сцены. Использование только WebGL ограничит пользовательскую базу, и это сложно реализовать (Unicodetiles имеет автоматический резервный механизм).


Другая библиотека, которую я слышал , предложил много в последнее время rot.js . Он специально предназначен для рогаликов, например, с системой FOV и генераторами подземелий. Если вы хотите полный пакет, это может быть путь.


Ницца. Я могу использовать это. Или, по крайней мере, учиться на том, как кто-то другой сделал это, чтобы проиллюстрировать мой собственный подход, поскольку я хочу сделать похожее на рогалика, но не так, как похожее на рогалика. : D
Kzqai

@Tapio Я пытаюсь реализовать pacman с помощью юникодилов, проблема в том, что игрок всегда центрирован на карте, это нежелательно для pacman, могу ли я как-то отключить его, или я могу обойтись без указания игрока.
user3995789

6

Я думаю, что наиболее эффективным способом было бы просто подделать его. Рендеринг в некоторый целевой элемент с использованием вашего собственного встроенного шрифта спрайта, как если бы вы рендерили обычный 2D-экран. Этот подход гарантирует, что странных вещей не случится, когда люди пропускают шрифты или используют совсем другой язык (китайский, русский).

Шрифты и тексты - одна из самых сложных вещей, чтобы получить идеальный пиксель во всех локалях во всех браузерах. Даже при встраивании шрифта и использовании какого-то волшебного CSS-браузера настройки юзабилити все равно можно переопределить и изменить. Для обычных веб-сайтов идеальный пиксельный текст не представляет проблемы, но в таких играх, как Dwarf Fortress, несколько пикселей могут привести к крайне непоследовательному виду. Даже если не браузер, а обычное приложение, есть проблемы с отображением текста. Так что даже сама Dwarf Fortress использует описанный мной подход.

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

На экранных дисплеях используется слегка измененная кодовая страница 437 символов в 16 различных цветах, реализованных в виде растровых изображений, визуализированных с помощью OpenGL

Изменить: потому что я получил несколько комментариев, я немного расширил ответ


Являются ли другие языки не расширениями, а не заменой ASCII? Почему обычные текстовые сайты не «подделывают»?
Анко

1
Большинство проблем кодировки символов можно предотвратить с помощью кодировки UTF-8.
Филипп

Русский язык отличается от шрифта ASCII, а китайский еще более отличается. Обычный веб-сайт заботится об эстетике, которая включает в себя такие вещи, как глифы переменного размера, кернинг, приятный «поток» текста и т. Д. Игра, подобная DF, будет заботиться о регулярном размещении букв, что невозможно сделать надежно в веб-браузере.
Лиосан

1
@Liosan уверен, что может. Просто используйте объявление CSS, font-family:monospace;и веб-браузер будет использовать моноширинный шрифт по умолчанию.
Филипп

Я на самом деле не уверен, как это будет выгодно по сравнению со встроенным веб-шрифтом css monospace-family? Я имею в виду, что это потребовало бы большего рендеринга, возможно, это позволило бы решить проблемы с пробелами более надежно, но со встроенным шрифтом CSS не было бы никакого значения, если бы люди пропустили шрифт или использовали другой язык? Хотя я предполагаю, что это ограничит операции только набором символов встроенного веб-шрифта, хммм.
Kzqai

3

Чтобы узнать количество строк и столбцов, которые вам нужно вывести, вы должны проверить ширину и высоту окна и изменить его соответствующим образом. Не забудьте слушать события onResize и соответственно изменять ширину и высоту.

Когда вы хотите сделать это текстовым способом , вы можете сделать это, используя текст с моноширинным шрифтом и таблицу, где каждая ячейка содержит один символ.

Для адресации отдельных символов вы можете создать <table>с правильным количеством строк и столбцов, где каждый <td>имеет идентификатор, состоящий из его x- и y-координат. Таким образом, вы можете обращаться к отдельным ячейкам по идентификатору и изменять их innerHTML, чтобы изменить букву, и изменить их класс css, чтобы изменить их цвет.

Использование холста , однако, может быть быстрее, потому что вам не нужно манипулировать большим деревом DOM для каждого персонажа, которого вы должны заменить. Кстати, Dwarf Fortress делает то же самое. Символы, которые используются для представления объектов, на самом деле являются растровыми изображениями, а не выводом истинного текста, и они рисуются с использованием 2d графических API. Холст HTML5 хорошо оборудован для этого. Он имеет метод context.fillText, который позволяет рисовать текст на холсте. Это может быть использовано для рисования отдельных персонажей. Вы можете изменить размер и шрифт, управляя переменными context.font и цветом каждой буквы, вызывая context.fillStyle .

Обратите внимание, что вызов fillText сотни раз за кадр может быть медленным, поскольку растеризация шрифтов обходится дорого, и ни один из известных мне браузеров не использует кэширование. Это означает, что когда вы отрисовываете одно и то же письмо с одинаковыми настройками сто раз, оно будет повторно растеризовано сто раз. Чтобы повысить производительность, вы можете кэшировать растеризованный вид каждой буквы с каждым цветом на скрытом холсте, а затем нарисовать эти скрытые холсты, используя context.drawImage. . Копирование с одного холста на другой обычно происходит намного быстрее, чем растеризация шрифта.

В настоящее время я занимаюсь разработкой 2D-игры с использованием canvas и заметил, что самым большим пожирателем FPS был шрифт. Когда я добавил кэш для растеризованного текста, это значительно улучшило производительность.


Растровые шрифты - это тоже настоящий текстовый вывод! Я использую их в терминале все время. Кроме того, если холст работает быстрее, почему рендеринг текста в StackExchange не основан на холсте?
Анко

блин, теперь я хочу написать библиотеку для этого.
Филипп

@Anko терминал! = Веб-браузер. Какой именно текстовый рендеринг вы имеете в виду?
Филипп

1
Анко говорит, что, поскольку растровые шрифты являются истинно-текстовыми, он может использовать их в своем терминале - и тем самым он доказывает, что растровые шрифты - это истинно-текстовые.
Полярный

0

ОК, это всего лишь удар в темноте, и я не знаю, как это отразится.

В основном вы используете те же хитрые консоли (или терминал), которые использовались в старину. Сначала вы начнете с моноширинного шрифта. У вас есть M строк с N символов. Таким образом, вы просто помещаете текст в достаточно широкий div (width: N em?) И вставляете каждые N символов в разрыв строки; в этом случае <br/>вместо\n .

Хитрость заключается в замене буфера, либо char на char, либо всего содержимого сразу java-скриптом.

Если вы хотите по-настоящему конкретизировать, вы можете использовать @ font-face, чтобы везде был одинаковый моноширинный шрифт.


Я тоже думал об этом, но потом понял, что это не будет хорошей архитектурой, если вы хотите контролировать цвет и цвет фона для каждого персонажа.
Филипп

0

Думайте с точки зрения глифов. Отделите отображение текста от значения, стоящего за ним. Например:

(псевдокод)

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

display(glyph);

А затем в вашем базовом коде для определения атласа глифа просто сделайте что-то вроде:

Glyph.Asterisk = "*";

Атлас глифа может фактически быть поиском в таблице ASCII с различными кодировками. Суть здесь в том, чтобы просто отделить, когда отображать, с тем, что должно отображаться. Я бы порекомендовал сделать рамки с нуля. Это дало бы вам больше свободы.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.