Skip to content

鼠标追踪与视差 ​

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

学习目标 ​

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

核心语法 ​

  • renpy.get_mouse_pos
  • ATL function
  • parallax
  • hover
  • renpy.variant

可运行示例 ​

text
init python:
    def make_parallax(strength_x, strength_y):
        # 返回一个 (trans, st, at) 函数;每帧根据鼠标位置设置偏移
        def f(trans, st, at):
            mx, my = renpy.get_mouse_pos()
            w = float(config.screen_width)
            h = float(config.screen_height)
            # 把鼠标位置归一化到 [-1, 1],屏幕中心为 0
            nx = (mx / w) * 2 - 1
            ny = (my / h) * 2 - 1
            # 反向偏移更像“视差”(鼠标右移、背景左移)
            trans.xoffset = -nx * strength_x
            trans.yoffset = -ny * strength_y
            return 0          # 每帧调用
        return f

# 不同图层给不同强度:越靠前的层动得越多
transform parallax_bg:
    function make_parallax(15, 8)

transform parallax_mid:
    function make_parallax(35, 18)

transform parallax_fg:
    function make_parallax(70, 36)

教程正文 ​

让背景、立绘、UI 随鼠标轻微移动,产生“立体跟随”的视差感——常用于标题画面、菜单背景、CG 鉴赏。 核心是 ATL 的 function 语句 + renpy.get_mouse_pos() 每帧读取鼠标位置。

1. 最简单的鼠标视差 ​

text
init python:
    def make_parallax(strength_x, strength_y):
        # 返回一个 (trans, st, at) 函数;每帧根据鼠标位置设置偏移
        def f(trans, st, at):
            mx, my = renpy.get_mouse_pos()
            w = float(config.screen_width)
            h = float(config.screen_height)
            # 把鼠标位置归一化到 [-1, 1],屏幕中心为 0
            nx = (mx / w) * 2 - 1
            ny = (my / h) * 2 - 1
            # 反向偏移更像“视差”(鼠标右移、背景左移)
            trans.xoffset = -nx * strength_x
            trans.yoffset = -ny * strength_y
            return 0          # 每帧调用
        return f

# 不同图层给不同强度:越靠前的层动得越多
transform parallax_bg:
    function make_parallax(15, 8)

transform parallax_mid:
    function make_parallax(35, 18)

transform parallax_fg:
    function make_parallax(70, 36)

使用(在屏幕里叠加多层):

text
screen title_parallax():
    add "bg/sky.png"      at parallax_bg     # 远景动得少
    add "bg/city.png"     at parallax_mid    # 中景
    add "bg/leaves.png"   at parallax_fg     # 近景动得多

label start:
    show screen title_parallax
    "移动鼠标,画面会有纵深的跟随感。"

关键技巧:远景 strength 小、近景 strength 大,就有了“近快远慢”的真实视差。

2. 防止露边:稍微放大图层 ​

偏移会把图边缘移进画面,导致露出空白。解决:让每层比屏幕略大(zoom 一点点), 这样偏移时边缘始终在画面外。

text
transform parallax_bg:
    zoom 1.08            # 略放大,留出偏移余量
    function make_parallax(15, 8)

或在函数里改 trans.zoom = 1.08 并配合 xanchor/yanchor 0.5、xpos/ypos 0.5 居中。

3. 惯性 / 平滑(更高级、更顺滑) ​

直接跟随会有点“硬”。用插值让偏移缓慢追上目标,得到顺滑的惯性感:

text
init python:
    def make_smooth_parallax(strength_x, strength_y, smooth=0.12):
        state = {"x": 0.0, "y": 0.0}     # 闭包里保存当前偏移
        def f(trans, st, at):
            mx, my = renpy.get_mouse_pos()
            w = float(config.screen_width)
            h = float(config.screen_height)
            tx = -((mx / w) * 2 - 1) * strength_x   # 目标偏移
            ty = -((my / h) * 2 - 1) * strength_y
            # 每帧朝目标移动一小步(线性插值)
            state["x"] += (tx - state["x"]) * smooth
            state["y"] += (ty - state["y"]) * smooth
            trans.xoffset = state["x"]
            trans.yoffset = state["y"]
            return 0
        return f

transform smooth_bg:
    zoom 1.1
    function make_smooth_parallax(20, 12, smooth=0.1)

smooth 越小越“黏”(更慢更顺),越大越跟手。

4. 倾斜视差(伪 3D 卡片) ​

除了平移,还能让图随鼠标轻微旋转/倾斜,做出卡片立体感:

text
init python:
    def tilt(trans, st, at):
        mx, my = renpy.get_mouse_pos()
        w = float(config.screen_width); h = float(config.screen_height)
        nx = (mx / w) * 2 - 1
        ny = (my / h) * 2 - 1
        trans.rotate = nx * 4.0          # 左右倾斜 ±4°
        trans.yoffset = -ny * 15
        trans.xoffset = -nx * 15
        return 0

transform card_tilt:
    align (0.5, 0.5)
    function tilt

5. 鼠标悬停放大(hover zoom) ​

不是逐帧追踪,而是“鼠标在某控件上时放大”。屏幕语言的 hover 变体最简单:

text
transform hover_zoom:
    zoom 1.0
    on hover:
        ease 0.15 zoom 1.08
    on idle:
        ease 0.15 zoom 1.0

screen gallery():
    imagebutton:
        idle "thumb/cg1.png"
        action Show("cg1")
        at hover_zoom            # 悬停时平滑放大

6. 只在主菜单/标题启用 ​

视差很适合标题页。放进 screen main_menu() 的背景,或用 add ... at 叠加:

text
screen main_menu():
    add "gui/main_menu.png" at smooth_bg
    # ...原有按钮...

常见坑 ​

  • renpy.get_mouse_pos() 返回的是虚拟分辨率坐标,配 config.screen_width/height 归一化。
  • function 每帧跑 Python;图层别太多(3~5 层足够),否则吃 CPU。
  • 偏移会露边 → 给图层 zoom 1.05~1.1。
  • 鼠标长时间不动会被隐藏(config.mouse_hide_time);视差仍按最后位置渲染,正常。
  • 移动端没有鼠标;这类效果主要面向桌面/网页端,必要时按 renpy.variant 关闭。

官方参考 ​

在 GenPy 里怎么做 ​

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

推荐继续阅读:

Built for GenPy creators.