零基础开发 era 游戏 #11 HTML_PRINT

转眼竟然更到第 11 期了,手上的干货存稿也基本上用完了。
之后就要现编 从零开始撰写了。

在原生 Emuera 里,HTML_PRINT 是我最喜欢的功能,没有之一。
它是 Emuera 几乎落后二十年的众多特性 / 设计里面唯一还算得上 现代 的。

总的来说,HTML_PRINT 就是把 PRINT 系的命令用 HTML 标签的形式重新实现了一遍。
那我们为什么不直接用 PRINT 系,而要用 HTML_PRINT 呢?
因为 HTML_PRINT 给了我们对「输出内容」无与伦比的控制力。

HTML_PRINT 的原理是将给定的「字符串」以类似 HTML 的语法解析后依序打印到屏幕。
所以呢?
所以它需要且仅需要的输入是「一个字符串」,一个可以任你捏扁揉圆的 字符串

这意味着我们可以有条不紊地组织并排版需要输出的内容,最后一口气完美展现给玩家。
而不是纠结于各种乱七八糟花里胡哨的不同 PRINT 系命令到底该如何配合。

支持的 HTML 元素(标签)#

p#

段落,主要是利用 align 属性进行对齐。

1
2
3
4
5
<p align='left'>左对齐文本</p>

<p align='center'>居中文本</p>

<p align='right'>右对齐文本</p>

nobr#

内容不会因为超过窗口宽度而隐式换行,又因为 Emuera 和浏览器不同,不会出现横向的滚动条,超过范围的部分会被直接丢弃(类似 PRINTSINGLE)。

1
<nobr>无论你在里面写多长都只会显示在单行</nobr>

注意在这个标签之外不能存在文本内容(标签可以),比如:

1
2
3
<p align='center'><nobr>这样写是可以的</nobr></p>

左边不能有文本<nobr>这样写会报错</nobr>右边也不能有

br#

手动换行。需要注意的是它的效果只是显示换行(并没有真的换行)。
无论有多少个 <br>LINECOUNT / CLEARLINE 这样计算行数的命令都会将它视为一行。

CLEARLINE LINECOUNT
PRINTL 1. 第一行
PRINTL 2. 第二行
PRINTL 3. 即将被删掉的第三行
CLEARLINE 1
PRINTFORML 3. 在本行之前共有 {LINECOUNT} 行
HTML_PRINT "4. 第一行<br>   第二行<br>   第三行"
PRINTFORML 5. 在本行之前共有 {LINECOUNT} 行

button, nonbutton#

「按钮」和「已禁用的按钮」。

HTML_PRINT "<button value='按钮A' title='鼠标悬浮提示1'>按钮</button>"
HTML_PRINT "<nonbutton title='鼠标悬浮提示2'>已禁用的按钮(普通文本)</nonbutton>"
HTML_PRINT "<p align='left'><nobr><button value='按钮B' title='鼠标悬浮提示3' pos='500'>偏移 500% 个字的按钮(左对齐且限定单行的前提下)</button></nobr></p>"
HTML_PRINT "<nobr><nonbutton title='鼠标悬浮提示4' pos='1000'>偏移 1000% 个字的文本</nonbutton></nobr>"
INPUTS

如上所示,如果想使用 pos 属性指定偏移量,必须保证为「左对齐」且「单行显示<nobr>」。
此时 pos 的单位是「1% 字体尺寸」。

font#

修改了字体和颜色的文本。

1
<font face='字体' color='颜色' bcolor='作为按钮被选中时的颜色'>文本</font>
HTML_PRINT "<button value='123' title='蓝色的字变成红色了'><font face='楷体' color='#147bdf' bcolor='red'>文本</font></button>"
INPUT

b, i, u, s#

带有 粗体 / 斜体 / 下划线 / 删除线 / 当然也可以互相嵌套 各类字体样式的文本。

1
2
3
4
5
6
7
8
9
<b>粗体</b>

<i>斜体</i>

<u>下划线</u>

<s>删除线</s>

<b><i><u><s>当然也可以互相嵌套</s></u></i></b>

img#

渲染图片,与 PRINT_IMG 的效果相同。

指定的 sprite 来自 ./resources/ 载入的图片,或用 SPRITE 系列命令生成的图像。

描画インターフェース:WINAPI 时,不会进行阿尔法rgba 的 a(透明度)通道的混合处理。

1
<img src='图像sprite名字' srcb='作为按钮被选中时的图像sprite名字' height='高度'>

注意 srcb 属性指定的图像会被放大 / 缩小到与 src 相同的尺寸。
因此为了保证良好的显示效果,应该尽量使用大小一致的图像(差分)。

指定的高度 height 属性会决定图像最后显示的大小,单位是「1% 字体尺寸」。
省略时默认为 100;当图像高度为负数(< 0)时会纵向翻转图像。

可以指定宽度 width 属性,省略时默认为 0(此时按照原图横纵比自动缩放);
当图像宽度为负数(< 0)时会横向翻转图像。

还可以指定纵轴座标 ypos 属性,单位是「1% 字体尺寸」,省略时默认为 0
(调整横轴座标可以使用 <shape type='space'> 标签或 <button> 标签的 pos 属性。)

shape#

1
2
<shape type='rect' param='绘制矩形的参数' color='颜色' bcolor='作为按钮被选中时的颜色'>
<shape type='space' param='绘制空白的参数'>

分别对应 PRINT_RECT / PRINT_SPACE 的效果。

type 属性为 rect 时绘制一个矩形,此时 param 属性可以拥有 4 个或是 1 个参数:

  • 4 个参数:分别对应「x 座标」「y 座标」「宽度(width)」「高度(height)」。
  • 1 个参数:宽度为「参数」×「1% 字体尺寸」,高度自动填满字体高度。
    (可以认为单个参数时自动取 0, 0, 单个参数, 100。)

type 属性为 space 时绘制一个空白区域(可以作为占位符),param 属性与绘制矩形时取单个参数的效果相同。

HTML 实体#

理论上所有 HTML 实体都是有效的,包括但不限于:

简单举例还有很多
HTML 实体&
&amp;
<
&lt;
>
&gt;
"
&quot;
'
&apos;
HTML ASCII
十进制写法
&
&#38;
<
&#60;
>
&#62;
"
&#34;
'
&#39;
HTML ASCII
十六进制写法
&
&#x26;
<
&#x3c;
>
&#x3e;
"
&#x22;
'
&#x27;

注释#

1
<!-- 注释的内容 -->

相关函数(一般用不上)#

一般函数(命令)#

HTML_TAGSPLIT:以 HTML 标签语法分割字符串。
分割后的「结果」保存在 RESULTS 数组内,「数量」保存在 RESULT(指 RESULT:0)。

行内函数#

HTML_POPPRINTINGSTR()

试了下没测出来到底是什么效果,摆了

現在 PRINT 中で改行待ちの文字列バッファを Html 形式で取得し、バッファを空にします
p タグはつかないので ALIGNMENT 命令による align は反映されません。

HTML_GETPRINTEDSTR(line_index)

在已显示的内容中,将第 line_index 行的内容解析为 HTML 字符串。
注意行数的计算方法与 LINECOUNT / CLEARLINE 命令相同(无视 <br> 算作一行)。

HTML_ESCAPE(html_text)

将参数 html_text 中的标签符进行转义。

HTML_TOPLAINTEXT(html_text)

将参数 html_text 以 HTML 格式解析,去除标签后转换为纯文本。

进阶用法#

通用工具函数#

;----------------------------------------------------------------
; 生成空白占位符 HTML
;----------------------------------------------------------------
@get_space_html(width=1)
#FUNCTIONS
    #DIM width
    width = width > CLIENTWIDTH() / GETCONFIG("フォントサイズ") ? width # width * 100
    RETURNF @"<shape type='space' param='{width}'>"
;----------------------------------------------------------------
; 生成文本 / 按钮 HTML
;----------------------------------------------------------------
@get_text_html(text, style=0, color="", tooltip="", button="", bcolor="", font="")
#FUNCTIONS
    #DIMS text
    #DIM style
    #DIMS color
    #DIMS tooltip
    #DIMS button
    #DIMS bcolor
    #DIMS font
    #DIMS html
    SIF GETBIT(style, 0)
        text '= @"<b>%text%</b>"
    SIF GETBIT(style, 1)
        text '= @"<i>%text%</i>"
    SIF GETBIT(style, 2)
        text '= @"<s>%text%</s>"
    SIF GETBIT(style, 3)
        text '= @"<u>%text%</u>"
    SIF STRFINDU(color, "#") != 0 && COLOR_FROMNAME(color) == -1
        color '= @"#%TOSTR(GETCOLOR(), "X6")%"
    SIF STRFINDU(bcolor, "#") != 0 && COLOR_FROMNAME(bcolor) == -1
        bcolor '= @"#%TOSTR(GETFOCUSCOLOR(), "X6")%"
    SIF !CHKFONT(font)
        font '= GETFONT()
    SIF button == "" && tooltip == ""
        RETURNF @"<font face='%font%' color='%color%' bcolor='%bcolor%'>%text%</font>"
    html '= button == "" ? "<nonbutton" # @"<button value='%button%'"
    html += @" title='%tooltip%'>"
    html += @"<font face='%font%' color='%color%' bcolor='%bcolor%'>%text%</font>"
    html += button == "" ? "</nonbutton>" # "</button>"
    RETURNF html

使用范例#

@SYSTEM_TITLE
    CALL TEST_HTML_PRINT_FUNC
    QUIT


@TEST_HTML_PRINT_FUNC
    #DIMS equipment_desc, 3
    #DIM CONST FONT_B = 1p0  ; 1
    #DIM CONST FONT_I = 1p1  ; 2
    #DIM CONST FONT_S = 1p2  ; 4
    #DIM CONST FONT_U = 1p3  ; 8
    #DIMS DYNAMIC html

    HTML_PRINT get_text_html("粗体", FONT_B)
    HTML_PRINT get_text_html("斜体", FONT_I)
    HTML_PRINT get_text_html("删除线", FONT_S)
    HTML_PRINT get_text_html("下划线", FONT_U)
    HTML_PRINT get_text_html("斜体+删除线+下划线", FONT_I|FONT_S|FONT_U)
    HTML_PRINT "<br>" * 2

    HTML_PRINT @"<p align='center'>%get_text_html("战斗胜利", FONT_B, "green")%</p>"
    html '= "<br>"
    html += get_space_html(14)
    html += get_text_html("获得经验值", FONT_B)
    html += get_space_html()
    html += @"%get_text_html("1,234,567", , "blue")% exp (%get_text_html("升级!", FONT_I)%)"
    html += "<br>"
    html += get_space_html(14)
    html += get_text_html("获得金币", FONT_B)
    html += get_space_html(350)
    html += @"%get_text_html("76,543", , "yellow")% G"
    html += "<br>"
    html += get_space_html(14)
    html += get_text_html("获得物品", FONT_B)
    html += get_space_html(2)
    equipment_desc:0 '= "索利达尔,群星之怒(传说)\n物品等级: 164\n拾取后绑定\n唯一\n远程 弓\n113 - 154 伤害 速度 3.00 (+ 44.5 伤害 / 每秒)\n+21 敏捷\n+32 耐力\n+20 爆击\n+21 急速\n需要等级 70\n装备:索利达尔在弓弦张开时会自动制造魔法箭。\n“太阳之井的能量流遍索利达尔的弓身。”"
    html += @"%get_text_html("索利达尔,群星之怒", , "orange", equipment_desc:0)%"
    html += "<br>"
    html += get_space_html(2020)
    equipment_desc:1 '= "奥伯莱恩,裂魂之剑(史诗)\n物品等级: 164\n拾取后绑定\n双手 双手剑\n120 - 201 伤害 速度 3.60 (+ 44.6 伤害 / 每秒)\n+24 力量\n+29 耐力\n+16 爆击\n+12 急速\n需要等级: 70\n装备:攻击强度提高126点。"
    html += @"%get_text_html("奥伯莱恩,裂魂之剑", , "violet", equipment_desc:1)%"
    HTML_PRINT html
    HTML_PRINT "<br>" * 2

    equipment_desc:2 '= "炉石(普通)\n物品等级: 1\n拾取后绑定\n唯一\n使用:将你传送回 碎日营地。与城镇中的旅店老板交谈可以改变你所设定的家的位置。"
    html '= @"你使用了%get_text_html("炉石", FONT_I, "#63d0ea", equipment_desc:2)%。"
    html += "<br>"
    html += @"你回到了%get_text_html("奎尔丹纳斯岛", FONT_I, "darkred", "「破碎残阳」领地\n中立 安全区")%。"
    html += "<br>" * 2
    html += @"%get_text_html("厄里斯·晨炉", FONT_B, , "「碎日先遣军」军官\n当前位于 碎日营地")%上校惊讶极了。"
    html += "<br>"
    html += "「噢!你竟然真的做到了!我必须马上回去禀报王上。」"
    html += "<br>"
    html += @"「你能把%get_text_html("奥伯莱恩,裂魂之剑", FONT_I, "violet", equipment_desc:1)%暂借给我作为证明吗?」"
    html += "<br>" * 2
    html += @"要%get_text_html("相信", FONT_U, , "这个选择将会影响 NPC 和你之间的关系")%他吗?"
    html += "<br>" * 2
    html += get_text_html("当然可以", FONT_B|FONT_U, "cyan", "需要交出「奥伯莱恩,裂魂之剑」", "你选择相信他。")
    html += get_space_html(2)
    html += get_text_html("不,你是个骗子", FONT_B|FONT_U, "cyan", "该选项造成的后果无法回溯!", "你选择质疑他。")
    HTML_PRINT html

    INPUTS

    SIF RESULTS == "你选择相信他。"
        HTML_PRINT @"失去 %get_text_html("奥伯莱恩,裂魂之剑", FONT_I, "violet", equipment_desc:1)%"

lackbfun © 2021 - 2024