鼠标追踪与视差
本页属于 GenPy Ren'Py 学习路线。教程内容面向 Ren'Py 8.x,并在页面末尾连接到 GenPy 的对应工作流。
学习目标
- 了解“鼠标追踪与视差”在 Ren'Py 项目中的用途。
- 能在一个最小项目里验证本章相关语法或工作流。
- 知道发布前需要检查的常见风险,并能在 GenPy 中继续维护。
核心语法
renpy.get_mouse_posATL functionparallaxhoverrenpy.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 tilt5. 鼠标悬停放大(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关闭。
官方参考
- ATL
function:https://www.renpy.org/doc/html/atl.html - 取鼠标坐标:
renpy.get_mouse_pos()https://www.renpy.org/doc/html/other.html
在 GenPy 里怎么做
- 在 GenPy 的代码模式中维护相关 .rpy 文件,先保持语法清晰,再逐步加入本章功能。
- 用故事图谱、变量、校验或演出编辑器把“能运行”提升到“可维护”。
- 导出前结合 Ren'Py Lint 和 GenPy 校验结果,确认脚本、素材和发布路径一致。
推荐继续阅读:
