制作主菜单
Luckykeeper 2022/5/9
本节文档介绍如何制作主菜单,本篇难度较高,强烈建议搭配源码学习
官方文档1:https://www.renpy.cn/doc/gui.html#
官方文档2:https://www.renpy.cn/doc/screen_special.html#main-menu
# 前置知识
textbutton、imagebutton,见“QuickMenu(快捷菜单)的制作”一节
相对坐标表示法、绝对坐标表示法,见“添加不同大小的小头像”一节
# 需求描述
默认的主菜单非常丑,我们需要做一个更好看一点的主菜单
# 修改代码
# 默认实现
先来看 Ren'Py 的主菜单默认实现
# 参考 ver1.0 screen.rpy 768-791行
screen main_menu(): # screen,声明这是一个界面
## 此语句可确保替换掉任何其他菜单界面。
tag menu # 各个菜单都要使用
add gui.main_menu_background # config 里面定义的背景图片
## 此空框可使标题菜单变暗。
frame:
style "main_menu_frame"
## “use”语句将其他的界面包含进此界面。标题界面的实际内容在导航界面中。
use navigation # navigation 是一个菜单的模板,本作移植版1.0版为纪念demo版,保留了开始菜单的 config 页面使用 navigation 模板
if gui.show_name: # config 里面的一个配置项,是否在主菜单表示游戏名称,做出来效果非常丑
vbox:
style "main_menu_vbox"
text "[config.name!t]":
style "main_menu_title"
text "[config.version]":
style "main_menu_version"
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 修改
参考下面 main_menu()
以及 main_menu_2()
的实现
# 参考 ver1.0 screen.rpy 514-762行
# 删除了部分无关注释
# 新 Main_Menu ,采用图片 Button 进行引导
screen main_menu(): # 首先声明一个页面,需要注意这里和默认实现同名所以需要注释掉原默认实现(参考 ver1.0 screen.rpy 768-791行),或者将默认实现的代码删除
## tag menu 的作用是来清其它界面,确保不被覆盖
tag menu
# 也可以直接引入一张图片
add "gui/main_menu/main_menu_1.png" # 引入主菜单的背景图
# 因为按钮大小不一,单独定制位置
# Start btn 的 vbox
vbox: # vbox 会把里面的内容用垂直定位的方法排列,在一个 box 里面放多个内容时非常好用,这里的设计思想类似 HTML 的盒模型,如果懂点儿 HTML 知识的话写这个应该会很简单
# 用 box 的好处是不会图片重叠,详见下面 main_menu2() 的实现
# 定位 参考前面的相对坐标表示法
## xalign 1.0->在最左边
## yalign 0->在最上面
xalign 1.0
yalign 0
imagebutton:
# Start btn 放大到 1080p 对应的大小是 380x193 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_start_base.png"
hover "gui/main_menu/btn_start_onMouse.png"
selected_hover "gui/main_menu/btn_start_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action Start()
# Load btn 的 vbox
vbox:
# 定位
xalign 0.891
yalign 0.25
imagebutton:
# Load btn 放大到 1080p 对应的大小是 191x304 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_load_base.png"
hover "gui/main_menu/btn_load_onMouse.png"
selected_hover "gui/main_menu/btn_load_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("game_load")
# Q.Load 功能
$ latest_file = renpy.newest_slot(regexp=None)
default l_f_page = "auto"
default l_f_name = "1"
# 似乎不影响运行,用 try 来跑,转最下
# Q.Load btn 的 vbox
vbox:
# 定位
xalign 1.0
yalign 0.25
if persistent.gameStarted: # 防止没有开始游戏就去点击导致的出错,这里同样是使用了持久化变量,后面会讲,这里不懂不要紧
imagebutton:
# Q.Load btn 放大到 1080p 对应的大小是 191x304 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_qload_base.png"
hover "gui/main_menu/btn_qload_onMouse.png"
selected_hover "gui/main_menu/btn_qload_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action [FileLoad(name=l_f_name, confirm=True, page=l_f_page)]
# Config btn 的 vbox
vbox:
# 定位
xalign 1.0
yalign 0.64
imagebutton:
# Config btn 放大到 1080p 对应的大小是 191x304 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_config_base.png"
hover "gui/main_menu/btn_config_onMouse.png"
selected_hover "gui/main_menu/btn_config_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("preferences")
# Extra btn 的 vbox
## Extra 涉及到周目,由可变的 btn 组成,根据周目变量变化
## Extra 功能待做
vbox:
# 定位
xalign 0.891
yalign 0.64
if persistent.one: # 一周目完成之后可以进入 Extra
# if 1==1: # 调试用
imagebutton:
# Extra btn 放大到 1080p 对应的大小是 191x304 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_extra_base.png"
hover "gui/main_menu/btn_extra_onMouse.png"
selected_hover "gui/main_menu/btn_extra_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("main_menu_2") # 在不同 Screen 之间切换的方法
# Project btn 的 vbox
# 官方 Website 莫得了,所以这里就换 Project 的 Website 好了
# 这个页面还没做,先跳转about页面
vbox:
# 定位
xalign 1.0
yalign 0.87
imagebutton:
# End btn 放大到 1080p 对应的大小是 381x125 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_project_base.png"
hover "gui/main_menu/btn_project_onMouse.png"
selected_hover "gui/main_menu/btn_project_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action OpenURL("https://love69renpyremasterproject.github.io/") # 这里展示了OpenURL()方法,后面也会讲
# End btn 的 vbox
vbox:
# 定位
xalign 1.0
yalign 1.0
imagebutton:
# End btn 放大到 1080p 对应的大小是 381x125 px ,稍稍大几个像素方便定位
## idle 初始状态
## hover 鼠标放在上面的状态
## selected_hover 按下 btn 的状态
idle "gui/main_menu/btn_end_base.png"
hover "gui/main_menu/btn_end_onMouse.png"
selected_hover "gui/main_menu/btn_end_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action Quit(confirm=True)
##################################################################################
# main_menu_2
screen main_menu_2():
## tag menu 的作用是来清其它界面,确保不被覆盖
tag menu
# 引入图片
add "gui/main_menu/main_menu_2.png"
vbox:
# 尝试统一定位
# 可以通过以下方法来排列图标,比上面的方法更好,处理图片时按比例缩放到指定宽度即可
# 这里就使用了 box 的美妙之处,不需要给每个 button 都指定位置了
xalign 1.0
yalign 0
# Gallery
hbox:
imagebutton:
idle "gui/main_menu/btn_cgmode_base.png"
hover "gui/main_menu/btn_cgmode_onMouse.png"
selected_hover "gui/main_menu/btn_cgmode_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("gallery")
# Replay
hbox:
imagebutton:
idle "gui/main_menu/btn_replaymode_base.png"
hover "gui/main_menu/btn_replaymode_onMouse.png"
selected_hover "gui/main_menu/btn_replaymode_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("replay")
# Music
hbox:
imagebutton:
idle "gui/main_menu/btn_bgmmode_base.png"
hover "gui/main_menu/btn_bgmmode_onMouse.png"
selected_hover "gui/main_menu/btn_bgmmode_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("music_room")
# ExtraGames
hbox:
imagebutton:
idle "gui/main_menu/btn_exgame_base.png"
hover "gui/main_menu/btn_exgame_onMouse.png"
selected_hover "gui/main_menu/btn_exgame_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action ShowMenu("extra_games")
# Back
hbox:
imagebutton:
idle "gui/main_menu/btn_omakeback_base.png"
hover "gui/main_menu/btn_omakeback_onMouse.png"
selected_hover "gui/main_menu/btn_omakeback_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
# 这里不能用 MainMenu() ,只能用 ShowMenu 来返回
action ShowMenu("main_menu")
# Exit
hbox:
imagebutton:
idle "gui/main_menu/btn_end_base.png"
hover "gui/main_menu/btn_end_onMouse.png"
selected_hover "gui/main_menu/btn_end_onClick.png"
hover_sound "voice/effect/マウス乗せ音.ogg"
activate_sound "voice/effect/メニュー決定音.ogg"
action Quit(confirm=True)
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232