马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Ren'Py引擎从入门到放弃(14)——GUI定制化之“Y/N”界面
世上无难事,只要肯放弃。
这是入门介绍的第十四篇,主要内容是GUI定制化,从相对比较简单的“是/否”型确认界面开始。
GUI定制化的大头是设计工作,脚本部分只是实现,没什么大不了的(大概)。难点在于细节繁琐,调试麻烦,容易掉头发……
感谢cexo同学提供的UI素材(以及催更要求)。
第一个问题:为什么选择“是/否”确认界面开始?
答:当然是因为这个界面最简单……嗯,虽然界面简单,涉及的要点依然不少。
“是/否”确认界面在脚本中称作 confirm screen,通常以小弹窗形式给出两个选项供玩家选择,比如退出游戏时默认弹出的 confirm界面如下:
弹出的confirm界面
首先我们来解读一下项目创建后默认的 confirm界面代码。默认在 screen.rpy文件中:
[RenPy] 纯文本查看 复制代码 screen confirm(message, yes_action, no_action):
## 显示此界面时,确保其他界面无法输入。
modal True
zorder 200
style_prefix "confirm"
add "gui/overlay/confirm.png"
frame:
vbox:
xalign .5
yalign .5
spacing 30
label _(message):
style "confirm_prompt"
xalign 0.5
hbox:
xalign 0.5
spacing 100
textbutton _("确定") action yes_action
textbutton _("取消") action no_action
## 右键点击退出并答复“no”(取消)。
key "game_menu" action no_action
style confirm_frame is gui_frame
style confirm_prompt is gui_prompt
style confirm_prompt_text is gui_prompt_text
style confirm_button is gui_medium_button
style confirm_button_text is gui_medium_button_text
style confirm_frame:
background Frame([ "gui/confirm_frame.png", "gui/frame.png"], gui.confirm_frame_borders, tile=gui.frame_tile)
padding gui.confirm_frame_borders.padding
xalign .5
yalign .5
style confirm_prompt_text:
text_align 0.5
layout "subtitle"
style confirm_button:
properties gui.button_properties("confirm_button")
style confirm_button_text:
properties gui.button_text_properties("confirm_button")
对关键词不了解的同学请对照官方文档查看详情:
界面与界面语言
可以看到,confirm界面包含两张图片、一个文字标签(label)和两个文本按钮(textbutton),其他的大多数代码都是管理布局的。所以,我们可以定制化的内容也就是这4个对象。yes_action 和 no_action 是 confirm界面自带的两个特殊行为(action)。目前GUI定制化不修改界面元素的功能。
把“confirm.png”图片替换成自己需要的,这种操作就不赘述了。
label里的入参“message”是由Ren'Py内部定义的,一般不会直接定义为常量字符串。定义来源在Ren'Py安装目录的renpy/common/00gui.rpy中。中文项目则在项目目录下/game/tl/None/common.rpym文件中,我们直接改这个就行了。根据文本搜索一下能找到:
[RenPy] 纯文本查看 复制代码 # renpy/common/00gui.rpy:378
old "Are you sure you want to quit?"
new "您确定要退出吗?"
注意这句是仅仅针对退出游戏时的confirm界面提示语,其他情况下的confirm提示语也在common.rpym文件中,请根据自己需要修改。(为了偷懒,这里我就稍微改几个字)
开头用 add语句添加的 gui/overlay/confirm.png是个与项目分辨率相同的图片。我新建的项目分辨率是1280*720,confirm.png就是个1280*720的灰色矩形(更准确的说是个黑色矩形,带一些透明度而已)。该图就是弹出confirm界面时,遮挡画面其他元素时的那层灰色。我们这里就仅仅调整一点原图的不透明度吧。
大部分样式(style)的内容是控制布局和文字显示效果,根据名字在gui.rpy文件中找到定义并修改即可(我觉得默认的样式就挺好的,不用修改,绝对不是我懒)。confirm_frame的定义中出现了两个图片名:gui目录下的confirm_frame.png和frame.png。Ren'Py会优先使用confirm_frame.png,如果没找到则使用frame.png;如果两个文件都没找到,就会报错……项目生成后默认只有frame.png,是个分辨率为600*250的黑色矩形。这里我们就直接加个confirm_frame.png吧。
这样修改的效果如图:
修改的效果
下面开刀的对象是两个按钮。我们需要把这两个按钮从 textbutton 改为 imagebutton,能稍微好看一点。我们可以把准备好的按钮图片放入game/gui/button目录下(并不强制要求放这个目录,只是为了规范),分别命名为:yes_hover.png、yes_idle.png、no_hover.png、no_idle.png,对应按钮的默认空闲状态和鼠标悬停状态。在脚本中将原本的两个 textbutton注释掉,添加上 imagebutton内容:
[RenPy] 纯文本查看 复制代码 imagebutton:
idle "gui/button/yes_idle.png"
hover "gui/button/yes_hover.png"
action yes_action
imagebutton:
idle "gui/button/no_idle.png"
hover "gui/button/no_hover.png"
action no_action
imagebutton内容
好的,confirm界面的定制化大体就完成了~
后面的内容只是一些“修修补补”的工作。
第二个问题:就这?有更风骚的定制化效果吗?
答:既然你们这样问了,那就再加亿点点效果吧……比如很常见的淡入淡出。
淡入淡出动画的核心,仅仅是hover图片的不透明度调整,所以只需要在获取到对应事件(event)时修改图像transform的 alpha值就可以了。
先定义transform:
[RenPy] 纯文本查看 复制代码 transform button_fadeinout:
alpha 0.0
on hover:
linear 0.5 alpha 1.0
on idle:
linear 0.5 alpha 0.0
on语句是上一篇提到过的考点,不清楚含义的同学请参考上一篇教程。
每个 imagebutton只能应用一个transform,所以直接把该 transform用到 imagebutton上,那么按钮的图片在 idle状态下就都是变成透明的了。
变成透明的
解决方案有多种,比如参考Ren'Py中文空间里 blackpineapple的帖子:
简单的 imagebutton图片变换
把 imagebutton改为父类button,将 idle状态的图片设为 background,hover状态的图片使用 add语句加上去。
[RenPy] 纯文本查看 复制代码 button:
background Image("gui/button/yes_idle.png", xalign = 0.5, yalign = 0.5)
add "gui/button/yes_hover.png" at button_fadeinout
action yes_action
button:
background Image("gui/button/no_idle.png", xalign = 0.5, yalign = 0.5)
add "gui/button/no_hover.png" at button_fadeinout
action no_action
还有个办法是把 imagebutton装进别的组件里作为子组件,imagebutton的父组件将 idle状态的图片设置为 background:
[RenPy] 纯文本查看 复制代码 frame:
background Image("gui/button/yes_idle.png", xalign = 0.5, yalign = 0.5)
imagebutton:
idle "gui/button/yes_hover.png" at button_fadeinout
action yes_action
frame:
background Image("gui/button/no_idle.png", xalign = 0.5, yalign = 0.5)
imagebutton:
idle "gui/button/no_hover.png" at button_fadeinout
action no_action
实现方法还有很多,我们这里就选取第一种吧(毕竟代码简单一些)。效果如下:
就选取第一种吧
回到淡入淡出 transform,仅仅修改 alpha值来实现动画效果。transform中可以用来做动画的 property还有很多,比如位置、旋转、缩放等等。详情可以参考官方文档:
transform特性列表
需要注意,位置、旋转、缩放往往会导致可视组件(displayable)所属的父组件的大小发生变化,所以很多自适应的布局都会产生奇怪的问题。目前最简单有效的解决方案是使用Fixed组件,规定每一个子组件的具体坐标。本篇暂不涉及这个问题,后续再详细说明。
第三个问题:按照这种实现方案,每新增一个按钮都要加两个图片,有没有节(tou)约(lan)的方案?
答:林语堂曾经说过“懒惰使人进步”,所以必须要有可以节约时间和存储空间的办法!
cexo同学提供的UI素材中总共有18张按钮图片,除了Yes/No之外,还有Save、Load、Log、Autoplay、Skip、System等(后续定制化快捷菜单界面会使用)。这些按钮的尺寸是完全一致的。各 idle状态的图片,只有图面文字不同,例如:
no_idle.png
no_idle.png
yes_idle.png
yes_idle.png
于是我把图片文字去掉后,命名为 button_idle_background.png:
button_idle_background.png
button_idle_background.png
两张hover状态图片的文字也去掉,命名为 button_no_hover.png 和 button_yes_hover.png:
button_no_hover.png
button_no_hover.png
button_yes_hover.png
button_yes_hover.png
注意,以上图片都有一个白色的描边,并不是一张纯色图。
使用 foreground 把文字“写”在按钮上:
[RenPy] 纯文本查看 复制代码 button:
background Image("gui/button/button_idle_background.png", xalign = 0.5, yalign = 0.5)
add "gui/button/button_yes_hover.png" at button_fadeinout
foreground Text("YES", xalign=0.5, yalign = 0.5, size = 15)
action yes_action
button:
background Image("gui/button/button_idle_background.png", xalign = 0.5, yalign = 0.5)
add "gui/button/button_no_hover.png" at button_fadeinout
foreground Text("NO", xalign=0.5, yalign = 0.5, size = 15)
action no_action
文本的大小和字体请与产品或设计确认。由于效果与使用带文字的图片差不多,这里就不放图了。
接着我们来点更风骚的操作,把 button_no_hover.png 和 button_yes_hover.png 也省了。
把 button_idle_background.png 处理一下,白色描边保留,中间填充使用纯黑色,不透明度调成100%:
button_idle_background.png
用绘图软件获取原图的色彩RGB值,分别为
- Yes“#ff6060”
- No "#62f4bf"
- idle "#5e5e5e",alpha大约0.45
最后使用Image Manipulator(图像处理器)上色和调整透明度:
[RenPy] 纯文本查看 复制代码 button:
background im.MatrixColor("gui/button/button_default.png", im.matrix.colorize("#5e5e5e", "#ffffff") * im.matrix.opacity(0.45), xalign=0.5, yalign = 0.5)
add im.MatrixColor("gui/button/button_default.png", im.matrix.colorize("#ff6060", "#ffffff"), xalign=0.5, yalign = 0.5) at button_fadeinout
foreground Text("YES", xalign=0.5, yalign = 0.5, size = 15)
action yes_action
button:
background im.MatrixColor("gui/button/button_default.png", im.matrix.colorize("#5e5e5e", "#ffffff") * im.matrix.opacity(0.45), xalign=0.5, yalign = 0.5)
add im.MatrixColor("gui/button/button_default.png", im.matrix.colorize("#62f4bf", "#ffffff"), xalign=0.5, yalign = 0.5) at button_fadeinout
foreground Text("NO", xalign=0.5, yalign = 0.5, size = 15)
action no_action
效果跟使用原图基本没差别:
效果跟使用原图基本没差别:
为了后续修改方便,可以把 RGB和 alpha值单独列在一个rpy文件中。例如,我新建了一个button_config.rpy文件,将后续会用到的几个按钮色彩值都定义为配置项:
[RenPy] 纯文本查看 复制代码 ## 按钮配色方案
define gui.button_bg_fill_color = "#5e5e5e"
define gui.button_bg_stroke_color = "#ffffff"
define gui.button_bg_alpha = 0.45
define gui.button_default_stroke_color = "#ffffff"
define gui.button_yes_hover_color = "#ff6060"
define gui.button_no_hover_color = "#62f4bf"
define gui.button_auto_hover_color = "#ff9a77"
define gui.button_auto_selected_idle_color = "#ff7357"
define gui.button_load_hover_color = "#8295f6"
define gui.button_log_hover_color = "#d789ff"
define gui.button_save_hover_color = "#74e7e8"
define gui.button_skip_hover_color = "#ff77a4"
define gui.button_skip_selected_idle_color = "#ff5585"
define gui.button_system_hover_color = "#ff98ea"
这种做法的主要目的是减少游戏目录内的图片数量,以及后续方案变更的修改便捷性。(设计人员只要出修改后方案即可,而不是做一台无情的出图机器)但设计原案的工作并不会因此减少。
完成版(为了贴近cexo的设计原案,调整了一下按钮位置):
[RenPy] 纯文本查看 复制代码 ## 自定义确认界面
screen confirm(message, yes_action, no_action):
## 显示此界面时,确保其他界面无法输入。
modal True
zorder 200
style_prefix "confirm"
add "gui/overlay/confirm.png"
frame:
vbox:
xalign .5
yalign .5
spacing 30
label _(message):
style "confirm_prompt"
xalign 0.5
hbox:
xalign 0.5
spacing 100
# textbutton _("确定") action yes_action
# textbutton _("取消") action no_action
button:
xoffset 50
background im.MatrixColor("gui/button/button_default.png", im.matrix.colorize(gui.button_bg_fill_color, gui.button_bg_stroke_color) * im.matrix.opacity(gui.button_bg_alpha), xalign=0.5, yalign = 0.5)
add im.MatrixColor("gui/button/button_default.png", im.matrix.colorize(gui.button_yes_hover_color, gui.button_default_stroke_color), xalign=0.5, yalign = 0.5) at button_fadeinout
foreground Text("YES", xalign=0.5, yalign = 0.5, size = 15)
action yes_action
button:
xoffset -50
background im.MatrixColor("gui/button/button_default.png", im.matrix.colorize(gui.button_bg_fill_color, gui.button_bg_stroke_color) * im.matrix.opacity(gui.button_bg_alpha), xalign=0.5, yalign = 0.5)
add im.MatrixColor("gui/button/button_default.png", im.matrix.colorize(gui.button_no_hover_color, gui.button_default_stroke_color), xalign=0.5, yalign = 0.5) at button_fadeinout
foreground Text("NO", xalign=0.5, yalign = 0.5, size = 15)
action no_action
## 右键点击退出并答复“no”(取消)。
key "game_menu" action no_action
gui.rpy文件中修改默认文本和交互组件文本的颜色(也可以在上面的脚本中在 Text那两行加个 color属性来实现):
[RenPy] 纯文本查看 复制代码 ## 用于对话和菜单选择文本的颜色。
define gui.text_color = u'#ffffff'
define gui.interface_text_color = u'#000000'
最终效果:
最终效果:
总结一下定制化“Y/N”确认界面的几个要素:
- 淡入淡出的transform;
- 图片按钮底图“button_default.png”;
- 按钮配色方案“button_config.rpy”;
- 修改screen.rpy和gui.rpy。
也不难的是吧,就是繁琐得很~
预告部分:下一篇应该是定制化导航界面,也就是主菜单和游戏内菜单。
|