在浏览器中(如矮人堡垒)构建ascii地图和移动角色的好的技术解决方案?[关闭]


10

我想为我的游戏网站构建一个网络应用程序,其中涉及使用文本字符来表示动物和人,并让它们通过独立的(服务器驱动)AI在地图方块上移动。

因此,本质上是浏览器中的矮人要塞地图: 矮人要塞的例子 移动的生物,生物,npc和pc。尽管不是我不想达到这样的规模,但我可能随时会开始显示大约四分之一的内容。

某些背景/固定瓷砖可能会被静态加载。但是对于生物/动物和可以移动的物体,我不确定哪种技术解决方案最有效。

我知道,<canvas>尽管我不知道其功能是否适合此用例。当然,将需要一定数量的javascript。

是否有适合该用例的javascript库或canvas库?我不知道的另一种技术?有人知道做过任何与此类似的网站的例子吗,这样我才能从中得到启发。



好吧,rot.js可能正是我在寻找的东西,但并不知道。
卡扎伊

Answers:


5

实际上,我已经为Web创建了一个字符显示库Unicodetiles.js,我不仅花费了一些时间对其进行了优化,而且还探索了呈现文本的不同方法。它具有三个渲染器:

  1. DOM,它使用<div>元素矩阵来呈现具有可自定义前景和背景颜色的每个字形。
  2. 画布,它使用<canvas>元素绘制字符。这要快得多,并且有性能测试对此进行了备份:http : //tapiov.net/unicodetiles.js/tests/
  3. WebGL,它使用画布元素创建字体纹理,然后使用WebGL进行渲染,WebGL速度更快,并且可缩放到较大的视口大小,但在浏览器中却不那么受支持。

请注意,链接的性能测试可能非常极端,每帧更改每个字符。实际上,即使是DOM渲染器,对于大多数用途来说也足够快。

如果您决定创建自己的库,我仍然建议您使用画布,因为它的性能似乎更好,允许更大的场景。仅使用WebGL将限制用户基础,并且实现起来很复杂(Unicodetiles具有自动回退机制)。


另一个库,我听说最近提出了很多的rot.js。它特别适用于Roguelike,因为它带有FOV系统和地牢生成器。如果您需要一个完整的软件包,可以采用这种方法。


真好 我可以用。或者至少是从别人的学习方法中汲取教训,以告知我自己的方法,因为我想做一个像流氓一样的人,而不是像一个流氓一样的人。:D
Kzqai 2013年

@Tapio我正在尝试使用unicodetiles实现pacman,问题是播放器始终位于地图的中心,这对pacman来说是不可取的,我可以以某种方式禁用它,还是可以在不指定播放器的情况下绕行。
user3995789

6

我认为最有效的方法就是伪造它。使用您自己的内置Sprite字体渲染到某些目标元素,就像渲染普通的2D屏幕一样。这种方法可以确保当人们缺少字体或使用非常不同的语言(中文,俄语)时,不会发生奇怪的事情。

在所有浏览器的所有语言环境中,字体和文本都是最难获得像素完美的东西之一。即使嵌入字体并使用某些CSS Magic浏览器,可用性设置仍可以覆盖和更改它。对于普通网站而言,像素完美的文本不是问题,但在《矮人要塞》等游戏中,几个像素可能会导致极其不连贯的视图。即使不使用浏览器而是使用普通应用程序,文本渲染也会出现问题。因此,甚至矮人要塞本身也使用了我描述的方法。

http://en.wikipedia.org/wiki/矮人堡垒

屏幕显示使用经过稍微修改的代码页437字符,这些字符以16位不同的颜色实现为位图,并使用OpenGL渲染

编辑:因为我有一些评论,所以我扩大了答案


是不是其他语言不是ASCII的扩展而是替代?通常包含文本的网站为何不“伪造”它?
Anko 2013年

1
使用UTF-8编码可以防止大多数字符编码问题。
菲利普

俄语的字体与ASCII的字体不同,中文的字体甚至更大。通常的网站关心美学,包括诸如可变大小的字形,字距调整,文本的“流动”等之类的东西。类似DF的游戏将关心字母的规则放置,这在Web浏览器中无法可靠完成。
2013年

1
@Liosan肯定可以。只需使用CSS声明font-family:monospace;,网络浏览器就会使用默认的等宽字体。
菲利普

我实际上不确定与嵌入式css monospace-family网络字体相比有什么好处吗?我的意思是,这将需要更多的渲染,这可能会更可靠地解决间距问题,但是使用嵌入式CSS字体,人们是否会丢失字体或使用其他语言都没关系?尽管我认为这会将操作限制为仅嵌入Web字体的字符集hmmm。
2013年

3

为了找出需要输出的行数和列数,您应该检查窗口的宽度和高度并相应地进行更改。记住要听onResize事件并相应地修改宽度和高度。

如果要以文本方式执行此操作,则可以使用具有等宽字体的文本和一个表格(其中每个单元格包含一个字符)来执行此操作。

要解决单个字符,您可以创建<table>具有正确数量的行和列的,其中每个<td>都有一个由x和y坐标组成的ID。这样,您可以按ID寻址单个单元格,并更改其innerHTML以更改字母,并更改其CSS类以更改其颜色。

但是,使用画布可能会更快,因为您不必为每个要替换的字符操纵大型DOM树。顺便说一句,矮人要塞也在做类似的事情。用于表示对象的字符实际上是位图,而不是真实的文本输出,它们是使用2d图形API绘制的。HTML5画布对此功能齐全。它具有context.fillText方法,可让您在画布上绘制文本。这可以用来绘制单个字符。您可以通过操纵变量的变化大小和字型context.font和每个字母的调用颜色context.fillStyle

请注意,每帧调用fillText数百次可能会很慢,因为光栅化字体非常昂贵,而且我所知没有浏览器使用缓存。这意味着当您用相同的设置渲染同一字母一百次时,它将被重新光栅化一百次。为了提高性能,您可以将每个字母的光栅化外观与每种颜色一起缓存在隐藏的画布上,然后使用context.drawImage绘制这些隐藏的画布。从一个画布复制到另一画布通常比字体光栅化要快得多。

我目前正在使用画布开发2D游戏,并且注意到最大的FPS使用者是字体绘图。当我添加栅格化文本的缓存时,它大大提高了性能。


位图字体也是真实文本输出!我一直在终端中使用它们。另外,如果画布速度更快,为什么StackExchange的文本渲染不基于画布?
Anko 2013年

该死的,现在我想为此写一个库。
菲利普

@Anko终端!= Web浏览器。您指的是什么文本渲染?
菲利普

1
Anko的说法是,因为位图字体是真实文本,所以他可以在终端中使用它们-因此,他证明了位图字体是真实文本。
2013年

0

好吧,这只是黑暗中的一击,我不知道它是如何呈现的。

基本上,您使用过去使用的相同的花样控制台(又名终端)。首先,您从等宽字体开始。您有M行N个字符。因此,您只需将文本转储到足够宽的div中(宽度:N em?),并每隔N个字符换行即可;在这种情况下,用a <br/>代替\n

诀窍是用java脚本一次替换char或全部内容的缓冲区。

如果您想变得非常具体,可以使用@ font-face来确保所有地方都有相同的等宽字体。


我也考虑过这样做,但是后来我意识到,当您想控制每个字符的颜色和背景颜色时,这不是一个好的架构。
菲利普

0

考虑字形。使文本的显示与其背后的含义脱钩。例如:

(伪代码)

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

display(glyph);

然后在用于定义字形图集的基础代码中,只需执行以下操作:

Glyph.Asterisk = "*";

字形图集实际上可以是对具有各种编码的ASCII表的查找。这里的重点仅仅是将何时显示与要显示的内容分开。我建议从头开始制作一个框架。它会给您更多自由。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.