找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 8359|回复: 1

[转载] Ren'Py引擎从入门到放弃(14)——GUI定制化之“Y/N”界面

[复制链接]
发表于 2021-1-26 16:24:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Ren'Py引擎从入门到放弃(14)——GUI定制化之“Y/N”界面



世上无难事,只要肯放弃。

这是入门介绍的第十四篇,主要内容是GUI定制化,从相对比较简单的“是/否”型确认界面开始。

GUI定制化的大头是设计工作,脚本部分只是实现,没什么大不了的(大概)。难点在于细节繁琐,调试麻烦,容易掉头发……

感谢cexo同学提供的UI素材(以及催更要求)。

第一个问题:为什么选择“是/否”确认界面开始?

:当然是因为这个界面最简单……嗯,虽然界面简单,涉及的要点依然不少。

“是/否”确认界面在脚本中称作 confirm screen,通常以小弹窗形式给出两个选项供玩家选择,比如退出游戏时默认弹出的 confirm界面如下:

弹出的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_actionno_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内容

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状态的图片设为 backgroundhover状态的图片使用 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

no_idle.png

yes_idle.png

yes_idle.png

yes_idle.png

于是我把图片文字去掉后,命名为 button_idle_background.png

button_idle_background.png

button_idle_background.png

button_idle_background.png

两张hover状态图片的文字也去掉,命名为 button_no_hover.pngbutton_yes_hover.png

button_no_hover.png

button_no_hover.png

button_no_hover.png

button_yes_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.pngbutton_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。


也不难的是吧,就是繁琐得很~

预告部分:下一篇应该是定制化导航界面,也就是主菜单和游戏内菜单。

发表于 2021-1-29 21:21:36 | 显示全部楼层
说起来 点击任务栏右上角的X触发的退出确认是写在哪里的? 我之前回答别人问题时没找到
回复 支持 抱歉

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-12-22 00:15 , Processed in 0.137748 second(s), 27 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表