持久化数据 link
Ren’Py支持持久化数据,保存游戏中与某个特定时间点无关的数据。通过绑定变量 persistent
的持久化对象字段(field),可以读写并实现持久化数据。
当Ren’Py进程结束时,所有与 persistent
关联的数据都会被保存,也可以通过调用 renpy.save_persistent()
。当Ren’Py启动或者检测到磁盘上的持久化数据更新过时,会加载持久化数据。
持久化对象有个特殊情况,就是接入一个未定义的字段时会得到一个None,而不是导致异常。 如果想要修改这种情况下的返回值,可以使用 default 语句:
default persistent.main_background = "princess_not_saved"
使用持久化的例子是创建一个能解锁的图片画廊。通过持久化存储一个标志(flag),就能判断画廊是否被解锁,比如:
label gallery:
if not persistent.gallery_unlocked:
show background
centered "你还没有解锁画廊。"
$ renpy.full_restart()
# 这里实际展示画廊。
当用于获得了某个解锁画廊的结局,这个标志(flag)必须设置为True。
$ persistent.gallery_unlocked = True
由于持久化数据在初始化Python语句块(block)之前加载,所以持久化数据应该只包含Python和Ren’Py的原生数据类型。不过,定义在 python early
语句块(block)中的类可以使用,提供的那些类可以被pickle和赋值。
合并持久化数据 link
有些时候Ren’Py需要合并源自两处的持久化数据。例如,Ren’Py可能需要合并来自USB驱动器和本地设备两个地方的持久化数据。
Ren’Py使用“字段对齐”的形式进行分析,最终使用各字段中更新事件更晚的值。在某些情况下,这不是我们需要的行为。这时,可以使用 renpy.register_persistent()
函数。
例如,如果我们有一个已经看过的结局的集合(set),我们合并数据时就希望取一个合集。
init python:
if persistent.endings is None:
persistent.endings = set()
def merge_endings(old, new, current):
current.update(old)
current.update(new)
return current
renpy.register_persistent('endings', merge_endings)
持久化函数 link
- persistent._clear(progress=False) link
重置持久化数据。
- progress
若为True,同时重置Ren’Py内部的进度数据。
请注意,该函数将删除所有持久化数据,并将所有变量设置为默认值。
- renpy.register_persistent(field, func) link
注册一个函数,用于合并磁盘上的持久化字段(field)值和当前持久化对象的值。
- field
持久化对象的字段(field)名。
- func
该函数使用 old 、 new 和 current 三个参数。
old
旧对象域的值。
- new
新对象域的值。
- current
当前持久化对象域的值。这个参数用于域引用的对象标识符无法改变的情况。
该函数需要返回持久化对象域的新值。
- renpy.save_persistent() link
将持久化数据保存到磁盘。
多个游戏数据的持久化 link
多游戏数据持久化是一个允许在多个Ren’Py游戏中共享信息的特性(feature)。如果你计划制作一个游戏系列,并在系列游戏中共同使用某些信息,就有可能用得上这个特性。
需要使用多元持久化数据,必须在初始化语句块(init block)中创建一个MultiPersisten对象。 用户可以更新这个对象,并调用其save方法保存至磁盘。 未定义的字段(field)默认值为None。 为了确保这个对象可以能再次正确加载,我们不建议使用用户自定义类型数据对象。
- class MultiPersistent(key, save_on_quit=False) link
创建一个新的MultiPersistent对象。这个类的构造函数应该只能在初始化语句块(init block)中调用,并根据给定的key创建一个新的MultiPersistent对象。
- key
用于接入多元持久化数据的key。使用相同key的游戏可以接入同一个多元持久化数据。
- save_on_quit
若为True,Ren’Py进程结束时自动保存该对象。
- save() link
将多元持久化数据保存至磁盘。当数据修改后必须调用这个函数。
这里的样例,选取了一个分成两部的游戏。这是第一部:
define mp = MultiPersistent("demo.renpy.org")
label start:
# ...
# 记录用户运行第一部的结果
$ mp.beat_part_1 = True
$ mp.save()
e "你打通了第一部。我们第二部再见!"
这是第二部:
define mp = MultiPersistent("demo.renpy.org")
label start:
if mp.beat_part_1:
e "你已经打通了第一步,欢迎来到第二部!"
else:
e "呣,你还没有玩过第一部,为什么不先试试第一部呢?"