设置和持久化变量

2022/5/16

本节文档介绍如何制作设置界面,本篇难度较高,强烈建议搭配源码学习

官方文档:https://www.renpy.cn/doc/persistent.html

# 前置知识

textbutton、imagebutton,见“QuickMenu(快捷菜单)的制作”一节

相对坐标表示法、绝对坐标表示法,见“添加不同大小的小头像”一节

# 需求描述

根据需要制作适应自己需要的设置界面

# 修改代码

这部分的制作方法其实和之前介绍的主菜单、存读档界面差不太多,只不过这里我们还需要通过持久化变量来实现更多设置功能

# 默认实现

先来看 Ren'Py 的主菜单默认实现,这里没有应用持久化变量

# 参考 提交 35e1328 链接: https://github.com/luckykeeper/LOVE69_renpy_remaster/blob/35e1328bce09152fc7ebaf9394102ccbb856c350/%E5%B7%B2%E5%AE%8C%E6%88%90%E7%9A%84%E6%96%87%E6%A1%A3/%E7%94%A8%E6%88%B7%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2/screens.rpy#L727 screen.rpy 727-818行
## 设置界面 ########################################################################
##
## 设置界面允许玩家配置游戏以更好地适应自己的习惯。
##
## https://www.renpy.cn/doc/screen_special.html#preferences

screen preferences():

    tag menu

    use game_menu(_("设置"), scroll="viewport"):

        vbox:

            hbox:
                box_wrap True

                if renpy.variant("pc") or renpy.variant("web"):

                    vbox:
                        style_prefix "radio"
                        label _("显示")
                        textbutton _("窗口") action Preference("display", "window")
                        textbutton _("全屏") action Preference("display", "fullscreen")

                vbox:
                    style_prefix "radio"
                    label _("回退操作区")
                    textbutton _("禁用") action Preference("rollback side", "disable")
                    textbutton _("屏幕左侧") action Preference("rollback side", "left")
                    textbutton _("屏幕右侧") action Preference("rollback side", "right")

                vbox:
                    style_prefix "check"
                    label _("快进")
                    textbutton _("未读文本") action Preference("skip", "toggle")
                    textbutton _("选项后继续") action Preference("after choices", "toggle")
                    textbutton _("忽略转场") action InvertSelected(Preference("transitions", "toggle"))

                ## 可以在此处添加类型为“radio_pref”或“check_pref”的其他“vbox”,
                ## 以添加其他创建者定义的首选项设置。

            null height (4 * gui.pref_spacing)

            hbox:
                style_prefix "slider"
                box_wrap True

                vbox:

                    label _("文字速度")

                    bar value Preference("text speed")

                    label _("自动前进时间")

                    bar value Preference("auto-forward time")

                vbox:

                    if config.has_music:
                        label _("音乐音量")

                        hbox:
                            bar value Preference("music volume")

                    if config.has_sound:

                        label _("音效音量")

                        hbox:
                            bar value Preference("sound volume")

                            if config.sample_sound:
                                textbutton _("测试") action Play("sound", config.sample_sound)


                    if config.has_voice:
                        label _("语音音量")

                        hbox:
                            bar value Preference("voice volume")

                            if config.sample_voice:
                                textbutton _("测试") action Play("voice", config.sample_voice)

                    if config.has_music or config.has_sound or config.has_voice:
                        null height gui.pref_spacing

                        textbutton _("全部静音"):
                            action Preference("all mute", "toggle")
                            style "mute_all_button"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

# 修改

# 参考 ver1.0 screen.rpy 1399-1572行
# 以下代码引自 NightBuild 版,稍有改动

# 可以注意到以下写了很多关于 persistent 的东西,这里就是在用持久化变量,下一标题将详细讲解

## 设置界面 ########################################################################
##
## 设置界面允许玩家配置游戏以更好地适应自己的习惯。
##
## https://www.renpy.cn/doc/screen_special.html#preferences
# 使用硬解
# https://www.renpy.cn/doc/config.html?highlight=config%20hw_video#var-config.hw_video

default persistent.hwVideo = False
define config.hw_video = persistent.hwVideo

########################
# 提升性能,用内存缓存提升加载速度
# 使用内存缓存(默认开启)
default persistent.useCache = True
define config.cache_surfaces = persistent.useCache

# HScene 梗图模式,默认关闭
default persistent.hsceneG = False

# persistent.mouseScroll 鼠标滚轮功能,默认关闭
default persistent.mouseScroll = False

# https://github.com/luckykeeper/LOVE69_renpy_remaster/issues/11
# 加入吐槽关闭功能
default persistent.luckykeeperSay = "full"
# 可选值
# full | 默认,全部开启
# meme | 只保留梗相关
# shutup | 全部不保留

screen preferences():

    tag menu

    use game_menu(_("设置"), scroll="viewport"):

        vbox:

            hbox:
                box_wrap True

                if renpy.variant("pc") or renpy.variant("web"):

                    vbox:
                        style_prefix "radio"
                        label _("显示")
                        textbutton _("窗口") action Preference("display", "window")
                        textbutton _("全屏") action Preference("display", "fullscreen")

                vbox:
                    style_prefix "radio"
                    label _("回退操作区")
                    textbutton _("禁用") action Preference("rollback side", "disable")
                    textbutton _("屏幕左侧") action Preference("rollback side", "left")
                    textbutton _("屏幕右侧") action Preference("rollback side", "right")

                vbox:
                    style_prefix "check"
                    label _("快进")
                    textbutton _("未读文本") action Preference("skip", "toggle")
                    textbutton _("选项后继续") action Preference("after choices", "toggle")
                    textbutton _("忽略转场") action InvertSelected(Preference("transitions", "toggle"))

                vbox:
                    style_prefix "check"
                    label _("实验选项,重启生效")
                    textbutton _("使用软解(稳定)") :
                        action [SetVariable("persistent.hwVideo",False),renpy.save_persistent()]
                        tooltip "默认选项,调用软件解码器对媒体进行解码,非常稳定但是耗费性能,对低端设备不友好"
                    textbutton _("使用硬解(更快)") :
                        action [SetVariable("persistent.hwVideo",True),renpy.save_persistent()]
                        tooltip "调用硬件解码器对媒体进行解码,速度快且高效,前提需要设备支持(程序的媒体文件有主要有png、webm、ogg、webp四种,请确保您的设备支持),可能会导致一些问题,如遇到视频拉伸,无法正常播放等问题,请切换回软件解码器,如果你的设备不属于低性能设备,强烈建议使用软件解码器"
                    textbutton _("使用内存缓存"):
                        action [SetVariable("persistent.useCache",True),renpy.save_persistent()]
                        tooltip "默认选项,素材文件预缓存至内存再从内存调用,运行速度大幅提升,对低内存设备不友好,但是只需要有1.2G以上空闲内存或开启了虚拟内存(一般系统都是默认开启的)就可以放心选择此项"
                    textbutton _("直接从硬盘读取") :
                        action [SetVariable("persistent.useCache",False),renpy.save_persistent()]
                        tooltip "程序直接从硬盘读取素材文件,只使用必要的内存,对硬盘性能要求高,但是内存开销较小,适合低内存设备,但是若硬盘读取性能不佳时可能会发生卡顿现象"

                vbox:
                    style_prefix "check"
                    label _("要加点儿梗嘛")
                    textbutton _("关闭HScene梗图模式(默认,推荐)") :
                        action [SetVariable("persistent.hsceneG",False),renpy.save_persistent()]
                        tooltip "默认选项,不看项目组瞎整活,调整该选项不影响HScene(因为根本没有),调整该选项理论上无需重启生效"
                    textbutton _("开启HScene梗图模式") :
                        action [SetVariable("persistent.hsceneG",True),renpy.save_persistent()]
                        tooltip "来看项目组胡乱整活,调整该选项不影响HScene(因为根本没有),请根据个人喜好谨慎开启,调整该选项理论上无需重启生效"

                # 鼠标滚轮只针对有鼠标的平台生效
                if renpy.variant("pc") or (renpy.variant("web") and not renpy.variant("mobile")):
                    vbox:
                        style_prefix "check"
                        label _("个性化")
                        textbutton _("禁用鼠标滚轮向下新对话") :
                            action [SetVariable("persistent.mouseScroll",False),renpy.save_persistent()]
                            tooltip "默认选项,鼠标滚轮仅用于回顾历史对话,需要重启生效"
                        textbutton _("启用鼠标滚轮向下新对话") :
                            action [SetVariable("persistent.mouseScroll",True),renpy.save_persistent()]
                            tooltip "使鼠标滚轮除回顾历史对话还能开始新对话,需要重启生效"
                ## 可以在此处添加类型为“radio_pref”或“check_pref”的其他“vbox”,
                ## 以添加其他创建者定义的首选项设置。
                    vbox:
                        style_prefix "check"
                        label _("吐槽等级(功能没做完请保持默认)")
                        textbutton _("火力全开(默认)") :
                            action [SetVariable("persistent.luckykeeperSay","full"),renpy.save_persistent()]
                            tooltip "加入对梗的解释和吐槽,理论上能让游戏过程更加有趣,如果不选此项,可能会影响到对剧情的理解"
                        textbutton _("只能有一点点") :
                            action [SetVariable("persistent.luckykeeperSay","meme"),renpy.save_persistent()]
                            tooltip "保留梗的解释和吐槽,去除吐槽部分和少部分必要的括号注释"
                        textbutton _("你闭嘴罢") :
                            action [SetVariable("persistent.luckykeeperSay","shutup"),renpy.save_persistent()]
                            tooltip "没有任何添加,感受纯天然的滋味"

            # https://www.renpy.cn/doc/screen_actions.html?highlight=gettooltip#tooltips
                $ tooltip = GetTooltip()

            if tooltip:
                text "[tooltip]"

            null height (4 * gui.pref_spacing)

            hbox:
                style_prefix "slider"
                box_wrap True

                vbox:

                    label _("文字速度")

                    bar value Preference("text speed")

                    label _("自动前进时间")

                    bar value Preference("auto-forward time")

                vbox:

                    if config.has_music:
                        label _("音乐音量")

                        hbox:
                            bar value Preference("music volume")


                    if config.has_sound:

                        label _("音效音量")

                        hbox:
                            bar value Preference("sound volume")

                            if config.sample_sound:
                                textbutton _("测试") action Play("sound", config.sample_sound)


                    if config.has_voice:
                        label _("语音音量")

                        hbox:
                            bar value Preference("voice volume")

                            if config.sample_voice:
                                textbutton _("测试") action Play("voice", config.sample_voice)

                    if config.has_music or config.has_sound or config.has_voice:
                        null height gui.pref_spacing

                        textbutton _("全部静音"):
                            action Preference("all mute", "toggle")
                            style "mute_all_button"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

# 二元属性变量设置

所谓“二元属性变量”就是指只有两种可能的变量,举例来说,就是只有“开启”和“关闭两种可能的设置”,这里我们通过“硬解”这个开关为例来具体讲解

“硬解”官方文档:https://www.renpy.cn/doc/config.html?highlight=config%20hw_video#var-config.hw_video

对于持久化变量,我们首先要给定一个默认值

# default 用来给持久化变量指定默认值
# 持久化变量的初始化方式: default persistent.变量名 = 值
# 这里使用的变量名就是 hwVideo
# 二元变量用 False 表示否定意义,用 True 表示肯定意义
default persistent.hwVideo = False
1
2
3
4
5

对于这里的硬解,我们是通过调用引擎里面的设置值来改变的,所以我们要让硬解的值与这里的持久化变量的值绑定

# 赋值方法:define config.hw_video(参见文档) = persistent.hwVideo(持久化变量)
define config.hw_video = persistent.hwVideo
# 在硬解hwVideo持久化变量的默认情况下,上面这个语句与下面这句等效,注意下面这句不是写到设置里面的内容
define config.hw_video = False
1
2
3
4

在做好以上准备后,我们就可以在设置里面的做按钮啦

                vbox:
                    style_prefix "check" # 使用 style "check" 的模板,这个模板是系统默认给的
                    label _("实验选项,重启生效") # label 大标题
                    textbutton _("使用软解(稳定)") : # 和前面的按钮一样,action 这里要稍复杂一点
                        action [SetVariable("persistent.hwVideo",False),renpy.save_persistent()] # action写法:[SetVariable("持久化变量全名",值),renpy.save_persistent()] ;renpy.save_persistent() 用来保存持久化变量
                        tooltip "默认选项,调用软件解码器对媒体进行解码,非常稳定但是耗费性能,对低端设备不友好" # tooltip 对设置选项的说明文字
                    textbutton _("使用硬解(更快)") :
                        action [SetVariable("persistent.hwVideo",True),renpy.save_persistent()]
                        tooltip "调用硬件解码器对媒体进行解码,速度快且高效,前提需要设备支持(程序的媒体文件有主要有png、webm、ogg、webp四种,请确保您的设备支持),可能会导致一些问题,如遇到视频拉伸,无法正常播放等问题,请切换回软件解码器,如果你的设备不属于低性能设备,强烈建议使用软件解码器"
1
2
3
4
5
6
7
8
9

# 三(多)元属性变量设置

大部分设置都是二元属性变量,但是如果需要设置的值多于二个的话怎么办呢?只需要在定义变量的时候像这样定义即可

# 以关闭吐槽功能为例
# 参考 NightBuild 1423-1429行
# https://github.com/luckykeeper/LOVE69_renpy_remaster/issues/11
# 加入吐槽关闭功能
default persistent.luckykeeperSay = "full"
# 可选值
# full | 默认,全部开启
# meme | 只保留梗相关
# shutup | 全部不保留
1
2
3
4
5
6
7
8
9

如上,定义的时候用字符串形式而不是布尔值的形式定义即可(当然用数字应该也是可以的),后面的内容是一样的,即可制作三(多)元属性变量设置