Skip to content

进阶GUI与自定义 ​

本页属于 GenPy Ren'Py 学习路线。教程内容面向 Ren'Py 8.x,并在页面末尾连接到 GenPy 的对应工作流。

学习目标 ​

  • 了解“进阶GUI与自定义”在 Ren'Py 项目中的用途。
  • 能在一个最小项目里验证本章相关语法或工作流。
  • 知道发布前需要检查的常见风险,并能在 GenPy 中继续维护。

核心语法 ​

  • Displayable
  • renpy.register_statement
  • custom text tags
  • callbacks
  • CDD

可运行示例 ​

text
init python:
    def buy(item):
        store.money -= item["price"]
        store.inventory.append(item["name"])

screen shop():
    vbox:
        for it in shop_items:
            textbutton "[it[name]] - [it[price]]金" action Function(buy, it)

教程正文 ​

当内置能力不够用时,Ren'Py 允许你用 Python 扩展:自定义可显示物、自定义语句、自定义文本标签、 各类回调。这是做复杂玩法(小游戏、特效、独特 UI)的关键。

1. 屏幕与 Python 协作 ​

  • 屏幕语言里可调用任意 Python 函数(action Function(fn)、SetVariable 等)。
  • 复杂数据准备放在 Python 函数里,屏幕只负责展示,保证刷新性能。
text
init python:
    def buy(item):
        store.money -= item["price"]
        store.inventory.append(item["name"])

screen shop():
    vbox:
        for it in shop_items:
            textbutton "[it[name]] - [it[price]]金" action Function(buy, it)

2. 自定义可显示物(Creator-Defined Displayable, CDD) ​

继承 renpy.Displayable,自己实现 render()(绘制)与可选的 event()(交互)。 适合做粒子、迷你游戏、自绘控件。

text
init python:
    class Spinner(renpy.Displayable):
        def __init__(self, child, **kwargs):
            super(Spinner, self).__init__(**kwargs)
            self.child = renpy.displayable(child)
            self.angle = 0

        def render(self, width, height, st, at):
            # st: 自显示以来的时间;用它驱动动画
            self.angle = (st * 90) % 360
            child_render = renpy.render(self.child, width, height, st, at)
            rv = renpy.Render(width, height)
            # ... 旋转绘制 child_render ...
            renpy.redraw(self, 0)        # 请求下一帧,形成动画
            return rv

image spinning_logo = Spinner("logo.png")

要点:

  • render(w, h, st, at) 返回一个 renpy.Render;st 是“显示时长”,用于动画。
  • renpy.redraw(self, delay) 让引擎在 delay 秒后重绘(驱动动画)。
  • 需要响应点击/拖拽时实现 event(ev, x, y, st)。

3. 自定义语句(Creator-Defined Statement, CDS) ​

用 renpy.register_statement 注册新脚本语句,让脚本更易读(如 nvl_clear、smartshow)。

text
python early:
    def parse_flash(lexer):
        color = lexer.string()
        lexer.expect_eol()
        return {"color": color}

    def execute_flash(o):
        renpy.show("_flash", what=Solid(o["color"]))
        renpy.with_statement(Dissolve(0.1))
        renpy.hide("_flash")

    renpy.register_statement(
        "flash",
        parse=parse_flash,
        execute=execute_flash,
    )

之后脚本里可写:

text
label start:
    flash "#fff"          # 自定义语句:闪白

8.5:register_statement 的 init_priority 现可传一个返回优先级的函数。

4. 自定义文本标签(Custom Text Tags) ​

注册 {xxx} 文本标签实现特效或语义化(见第 10 章):

text
init python:
    def emphasis_tag(tag, argument, contents):
        rv = [(renpy.TEXT_TAG, "b")]
        rv.extend(contents)
        rv.append((renpy.TEXT_TAG, "/b"))
        return rv
    config.custom_text_tags["em"] = emphasis_tag

使用:e "这是{em}重点{/em}。"

也可用 config.self_closing_custom_text_tags 注册自闭合标签(如 {ruby} 注音)。

5. 角色回调(Character Callback) ​

在角色说话的各阶段插入逻辑(播配音、特效、记录历史):

text
init python:
    def e_callback(event, interact=True, **kwargs):
        if event == "begin":
            renpy.play("audio/voice_blip.ogg")
        elif event == "show":
            pass
        elif event == "end":
            pass

define e = Character("艾琳", callback=e_callback)

event 取值:begin、show、show_done、slow_done、end 等。

6. 其它常用回调/钩子 ​

钩子时机
config.start_callbacks游戏开始
config.after_load_callbacks读档后
config.before_load_callbacks(8.5 新增 before_load label)读档前(可换显示/音效)
config.context_callbacks(8.5 新增)进入新上下文时(可多个)
config.interact_callbacks每次交互
config.python_callbacks每条 Python 语句后

7. _ren.py 文件(在纯 Python 里写 Ren'Py) ​

xxx_ren.py 文件让你用标准 Python 语法编写、被 Ren'Py 当作脚本加载,便于用 IDE 类型检查:

python
"""renpy
init python:
"""
def my_helper(x):
    return x * 2

常见坑 ​

  • CDD 的 render 要返回 renpy.Render,动画靠 renpy.redraw 持续请求重绘。
  • CDS 的 parse 在 python early: 注册,保证早于脚本解析。
  • 自定义文本标签返回的是“文本片段列表”,格式要对。
  • 回调里别做重 IO/阻塞操作,会卡帧。

官方参考 ​

在 GenPy 里怎么做 ​

  • 在 GenPy 的代码模式中维护相关 .rpy 文件,先保持语法清晰,再逐步加入本章功能。
  • 用故事图谱、变量、校验或演出编辑器把“能运行”提升到“可维护”。
  • 导出前结合 Ren'Py Lint 和 GenPy 校验结果,确认脚本、素材和发布路径一致。

推荐继续阅读:

Built for GenPy creators.