好久没有更新技术相关的东西了,最近在学习 renpy 引擎,然后有一点点发现想要分享。
我在做一个游戏,其中一个需求是,我的游戏的入口是界面,而不是对话。用户会在几个界面之间跳来跳去,可以没有对话,但是总是要有一个 UI 界面。所以我需要让它看起来是,进入游戏有个界面,玩家可以执行一些行动,比如点击某个按钮,然后再开始播放对话,有时还需要让这个 screen 作为背景。
但是 renpy 的核心是 label,而 label 如果没有文字内容,show screen 之后就结束了,所以理所当然想到在 label 中 call screen。于是得到了下面这段代码,当然,这里有一些小问题。
label my_ui:
call screen my_ui_screen
screen my_ui_screen():
frame:
textbutton "播放对话A" action Jump("dialog_a")
label dialog_a:
"一些对话内容。"
jump my_ui
我开始这样写的时候,本来担心它没办法执行,因为我的离开片是 call screen 的时,my_ui 被阻塞了,但是最终发现还可以。当执行 jump 的时候,旧的 label 的上下文被销毁了,那个 my_ui_screen 也结束了,一个证据是,在 dialog_a 中,是看不到 my_ui_screen 的。
不过使用 Jump() 并不是一个好方案,这里推荐用 Call(),因为它会在 label return 后自动返回。
label my_ui:
call screen my_ui_screen
# 这里有一点点小问题,一会儿就知道了。
screen my_ui_screen():
frame:
textbutton "播放对话A" action Call("dialog_a")
label dialog_a:
"一些对话内容。"
return
然后就会得到了一个怪异的表现,dialog_a return 之后,本来应该回 my_ui,但是可能会播放其它的对话,又或者直接结束,取决于有没有更多的 label 以及它们的组织顺序。
哎?为什么没有阻塞在 call screen my_ui_screen 那里?在 Call 或者 Jump 的时候,my_ui_screen 的交互就已经「结束」了,于是 my_ui_screen 不被需要了。而,my_ui 在后面并没有更多的文字内容来呈现,于是 my_ui 也结束了。renpy 可能会试图找到「后面的」对话,如果没有的话就回到主菜单了。
所以改进之后的版本,要让 my_ui 在末尾跳转自己。
label my_ui:
call screen my_ui_screen
jump my_ui
然后,前面提到到达 dialog_a 的时候,是没有 my_ui_screen 呈现的。所以如果我想要让这个界面留在屏幕上当作对话的背景,我还需要在 dialog_a 的开头,show screen my_ui_screen。
label dialog_a:
show screen my_ui_screen
"一些对话内容。"
return
然后,很有意思的一点是,dialog_a 不需要在结束的时候 hide screen。可以对 my_ui_screen 做一点小改动,来观察这个现象。
screen my_ui_screen(is_show = False):
frame:
text ("show" if is_show else "call")
textbutton "播放对话A" action Call("dialog_a")
label dialog_a:
show my_ui_screen(True)
"一些对话内容。"
menu:
"返回":
return
"播放对话B"
call dialog_b
return
label dialog_b:
"另一些对话内容。"
return
上面修改过的 my_ui_screen 会展示自己是 show 还是 call 出来的。如果 dialog_a 直接返回,那么会看到 my_ui_screen 从 show 版本变回 call 版本。而,如果去 dialog_b,则会发现 my_ui_screen 依然存在,没有消失,一直是 show 版本。
当然,这样证明有个漏洞,比如「有没有可能是 call 版本的 my_ui_screen 覆盖在了 show 版本的 my_ui_screen 上面」,还可以让 frame 半透明来确认。
不过总的来说,call screen my_ui_screen 把前一个版本的 show screen my_ui_screen 顶替了,因为 screen 还有个 tag 机制存在。「用来确保在相同的上下文环境下,同一时间只有显示一个菜单界面」,文档是这么说的。
结束。