找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 14365|回复: 9

[有回复] 关于screen、按钮和层叠组件的若干问题(详情见帖内)

[复制链接]
发表于 2019-7-26 23:04:16 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 鼠西 于 2019-7-26 23:11 编辑

这里正在尝试制作换装系统(顺带练习一下UI制作),最终装束将作为玩家的立绘在后面的剧情中继续使用
虽然基本功能实现的差不多了,但摸索过程中遇到一些问题想请教一下

下面是demo的代码,一些比较细碎的疑问在注释中标明了,大问题见下文:PS:另附界面示意图

[RenPy] 纯文本查看 复制代码
#——————————————————————————————————————————————————————————————
# 这部分可以先跳过

layeredimage sb:
    always:
        "sb_skin_default"
    group skin:
        attribute skin1 default:
            "sb_skin_1"
        attribute skin2:
            "sb_skin_2"
    group under:
        attribute under1 default:
            "sb_under_1"
        attribute under2:
            "sb_under_2"
        attribute under3:
            "sb_under_3"
    group top:
        attribute top1:
            "sb_top_1"
        attribute top2 default:
            "sb_top_2"
        attribute top3:
            "sb_top_3"
    group hair:
        attribute hair1 default:
            "sb_hair_1"
        attribute hair2:
            "sb_hair_2"
        attribute hair3:
            "sb_hair_3"
    group totem:    
        attribute totem1 default:
            "sb_totem_1"
        attribute totem2:
            "sb_totem_2"
        attribute totem3:
            "sb_totem_3"
    group face:
        attribute face1 default:
            "sb_face_1"
        attribute face2:
            "sb_face_2"
        attribute face3:
            "sb_face_3"

image avator_user = "sb skin%d hair%d top%d face%d under%d totem%d"%(skinnum,hairnum,topnum,facenum,undernum,totemnum)
image side_avator = LayeredImageProxy("avator_user", Transform(crop=(0, 0, 440, 440), xoffset=-550))

# 以上是运用层叠图形做的部位拼装,但遇到一些问题最终未采用
#————————————————————————————————————————————————————————————————————————



init python:
    facechoice = False  # 默认样式选择按钮不显示
    hairchoice = False
    topchoice = False
    undernum,topnum,skinnum,facenum,totemnum,hairnum = 1,1,1,1,1,1
    def draw_avator(st, at):  # 纸娃娃实时预览组件
        return LiveComposite(
            (460, 1020),
            (0, 0), "sb_skin_%d"%skinnum, #肤色
            (0, 0), "sb_face_%d"%facenum, #五官
            (0, 0), "sb_totem_%d"%totemnum, #面纹
            (0, 0), "sb_hair_%d"%hairnum, #发型
            (0, 0), "sb_under_%d"%undernum, #下装
            (0, 0), "sb_top_%d"%topnum, #上装
            ),.1  # 想问一下这个“.1”在这里是什么用法和意思?
 

transform button_b: 
    # 部位选择按钮焦点时放大的动态
    anchor (0.5 , 0.5)
    on idle:
        linear 0.1 zoom 1
    on hover:
        linear 0.1 zoom 1.2

transform slidd:
    # 用作mousearea触发按钮,从屏幕外滑入的动态
    pos(-135,0)
    on idle:
        linear 0.15 xpos 0
 
transform choiceframe_left:
    #左上角/右下角选择框的旋转和伸展动态
    anchor (0.5,0.5)
    rotate 30
    xzoom 0.0 yzoom 1.0
    linear 0.15 xzoom 1.0 yzoom 1.0

transform choiceframe_right:
    #右上角/左下角选择框的旋转和伸展动态
    anchor (0.5,0.5)
    rotate -30
    xzoom 0.0 yzoom 1.0
    linear 0.15 xzoom 1.0 yzoom 1.0

transform choiceframe_center:
    #中间选择框的伸展动态
    anchor (0.5,0.5)
    xzoom 0.0 yzoom 1.0
    linear 0.15 xzoom 1.0 yzoom 1.0

transform choicebutton:
    #样式选择按钮的渐入动态
    alpha 0.00
    0.3
    anchor (0.5,0.5)   
    linear 0.3 alpha 1.0

transform bgchange:
    #图片渐入动态
    alpha 0.1
    0.05
    alpha 0.2
    0.05
    alpha 0.3
    0.05
    alpha 0.4
    0.05
    alpha 0.5
    0.05
    alpha 0.6
    0.05
    alpha 0.7
    0.05
    alpha 0.8
    0.05
    alpha 0.9
    0.05
    alpha 1.0
    
init:
    #这里是照抄的,想问一下这个“init:”的用法是什么,和“init Python”有什么区别,如果这里不用“init”会怎样?
    image avator = DynamicDisplayable(draw_avator) 
    $ a = Character('avator', color="#a50303") # 这里 a 前面为什么需要加一个变量符号呢?

screen avatorchange:
    #描绘换装页面
    add "avatorbg" at bgchange  #背景图
    add "avator"  xpos 680 ypos 56  #预览纸娃娃
    textbutton "JUMP" action Jump(label="showtest") xpos 1800 ypos 1020  #跳转到后续剧情
    imagebutton:
        # 五官按钮
        pos (560 , 380)
        at button_b
        action SetVariable("facechoice",True)
        idle "facebutton_1"
        hover "facebutton_2" 
        selected_idle "facebutton_2"
    imagebutton:
        # 发型按钮
        pos (490 , 595)
        at button_b
        action SetVariable("hairchoice",True)
        idle "hairbutton_1"
        hover "hairbutton_2" 
        selected_idle "hairbutton_2"
    imagebutton:
        # 上装按钮
        pos (1408 , 595)
        at button_b
        action SetVariable("topchoice",True)
        idle "topbutton_1"
        hover "topbutton_2" 
        selected_idle "topbutton_2"



screen choiceframe2:
    zorder 1
    if facechoice:
        # 描绘五官样式选择按钮
        add "facechoiceframe" at choiceframe_left xpos 365 ypos 290
        textbutton "1" action SetVariable("facenum",1) xpos 297 ypos 247 at choicebutton
        textbutton "2" action SetVariable("facenum",2) xpos 364 ypos 282 at choicebutton
        textbutton "3" action SetVariable("facenum",3) xpos 429 ypos 320 at choicebutton

    if hairchoice:
        # 描绘发型样式选择按钮
        add "facechoiceframe" at choiceframe_center xpos 268 ypos 595
        textbutton "1" action SetVariable("hairnum",1) xpos 197 ypos 594 at choicebutton
        textbutton "2" action SetVariable("hairnum",2) xpos 270 ypos 594 at choicebutton
        textbutton "3" action SetVariable("hairnum",3) xpos 343 ypos 594 at choicebutton

    if topchoice:
        # 描绘上装样式选择按钮
        add "facechoiceframe" at choiceframe_center xpos 1630 ypos 595
        textbutton "1" action SetVariable("topnum",1) xpos 1550 ypos 594 at choicebutton
        textbutton "2" action SetVariable("topnum",2) xpos 1623 ypos 594 at choicebutton
        textbutton "3" action SetVariable("topnum",3) xpos 1696 ypos 594 at choicebutton


# 一个mousearea呼出菜单的测试
#————————————————————————————————————————————————————————————————————————————————————————

screen button_overlay():
    mousearea:
        area (0, 0, 400,100)
        hovered Show("buttonf")
        unhovered Hide("buttonf")        

screen buttonf():
    hbox:
        imagebutton:
            at slidd
            idle "facebutton_1"
            hover "facebutton_1"
            action ShowMenu("save")

#————————————————————————————————————————————————————————————————————————————————————————


# 游戏在此开始。
label start:

    a "这里是换装测试"

    show screen button_overlay
    show screen choiceframe2 with dissolve
    # 这里发现如果 choiceframe2 在 avatorchange 页面之后呼出会无法显示原因是什么呢?
    call screen avatorchange with dissolve 


label showtest:
    hide screen choiceframe2
    hide screen avatorchange
    scene bg with dissolve
    pause 0.1
    show avator with dissolve
    a "你的avator定制完毕"
    a "测试结束"

return    # 此处为游戏结尾。


Q1:最初因为看到版主介绍层叠组件想用这个方法来做,但发现无论image定义是否在部件num被改变后(在换装页面通过按钮改变变量后),显示出来的都是初始化时默认的“1”,所以最终还是按照老方法livecomposite来做。于是:
           q1.1:因为似乎层叠组件更加“先进”,如果想用这个方法做应该怎么修改才能让image返回改变后的外观?
           q1.2:层叠组件和Livecomposite组件两者之间,在实际使用中的区别是什么?各有什么优劣,理由是?(看了教程和文档还是比较懵)

Q2:这里希望实现的按钮效果是:每次只能选择一个部件,并弹出选择框,当玩家点选其他部件按钮时,当前按钮回归到idle状态。请问要如何才能做出这个效果?(目前点选后就只能一直保持开启状态了)

Q3:最初是想把选择框做成单向拉伸的(以左边界/右边界中点为锚点),但发现图片会在形变过程中会发生位移,故而改成以中心为锚点的方式。之前的代码是这样写的:
           transform choiceframe_left:
               anchor (0.5,1.0)
               rotate 30
               xzoom 0.0 yzoom 1.0
               linear 0.15 xzoom 1.0 yzoom 1.0
       请问错误出在哪里?要如何实现需要的效果?

Q4:有什么办法可以在screen模块中直接控制组件出现的顺序吗?比如背景先显示,按钮和纸娃娃后显示。目前暂时在transform最开头加入等待时间达到这个效果,但感觉这样太麻烦且不灵活。(另:1、2、3的textbutton能有先后顺序的显示出来吗?)

Q5:目前所有的动态效果都是用transform做的,直觉上感到这种做法好像有些太笨了,比如最简单的渐变也需要单独描述。是否有办法在screen中更简便地实现各类转场和动态?

Q6:这是一个有些奇怪的问题,关于脚本的精简:
          q6.1:如何调用其他rpy文件中的模块?(最初的层叠组件原本写在新建的脚本中,结果启动游戏完全没有效果,只好都放在了script里)
          q6.2:直觉上某些部分的外码可以“合成一块”变得更加简洁,按钮样式,变换样式等等,但没什么头绪,望指导。



(PS:这里不久前才开始学习python基础和Ren'py,一知半解,问题有点多且杂还请见谅,麻烦各位了!(鞠躬))






界面示意图

界面示意图
发表于 2019-7-28 08:52:09 | 显示全部楼层
鼠西 发表于 2019-7-27 01:01
↑关于Q2已经解决了! 把facechoice、hairchoice、topchoice去掉,改用同一个变量,例如 openpart = 0
设 ...

可以,用英文逗号“,”隔开。
SetScreenVariable是与screen相关变量赋值,相对于局部变量与全局变量。
做小示例:
[RenPy] 纯文本查看 复制代码
default mingzi = "共用名字"
default HP = 10

screen aaa():

    default mingzi = "aaa"
    text "在aaa里共用名字:[mingzi]" xpos 0.3

    vbox:
        text "aaa名字:[mingzi]"
        null height 20
        text "血量:[HP]"
        null height 20
        textbutton _("更改属性") action SetVariable("HP", 88),SetVariable("mingzi", "更改属性")
## 可注释掉下面按钮,看共用名字(即,变量名相同)变化。
        textbutton _("aaa更改名字") action SetScreenVariable("mingzi", "aaa更改名字")

screen bbb():

    default mingzi = "bbb"
    vbox:
        xpos 0.8
        text "bbb名字:[mingzi]"
        null height 20
        textbutton _("bbb更改名字") action SetScreenVariable("mingzi", "bbb更改名字")

# 游戏在此开始。
label start:

    show screen aaa()
    show screen bbb()
    "演示"

    # 此处为游戏结尾。
    return



回复 支持 2 抱歉 0

使用道具 举报

发表于 2019-7-28 10:35:11 | 显示全部楼层
Q1:看你上传示意图,建议用层叠式图像(layeredimage),游戏开始renpy会初始化,层叠式图像(layeredimage)必须有个默认值,就像人脸,显示这脸必须给个默认的眼睛、鼻子吧。不然初始化,会出现找不到文件的错误。
还有技巧:调用什么图片,可以用变量控制,可用一个按钮“返回默认值”,把各个变量改回:
[RenPy] 纯文本查看 复制代码
## 定义不同眼睛图片
image yanjing_1 = "g1.png"
image yanjing_2 = "cc.png"

## 定义不同鼻子图片
image bizi_1 = "g1.png"
image bizi_2 = "cc.png"

## 控制眼睛变量,默认值1。
default aaa = 1

## 控制鼻子变量,默认值2。
default bbb = 2


layeredimage ceshi:

    always:## 背景底图
        "base.png"

    group eyes:# 眼睛
        attribute jeans:
            "yanjing_[aaa]"

    group nose: # 鼻
        attribute wink:
            "bizi_[bbb]"

## 可以新建个按钮把变量aaa、bbb改回默认值。

和 Livecomposite的区别,看文档描述就知道了(注意加粗字体):
类图像的可视组件:我们将这些可视组件称作“类图像”,是因为他们占用界面中的一块矩形区域但不会对输入做任何反应。这有别于通常的图像,这些“类图像”可以调整尺寸填充某个区域(Frame、LiveTile、Solid),或者允许用户指定尺寸(LiveComposite、LiveCrop、Null)。他们自身不能操作图像


Q2:见Q1

Q3:未测试,大概是,旋转最好正方形,位置用将pos和anchor设置为相同的值align。

Q4:可以做出不同的screen,再逐个Show或use语句,也可以用 timer控制


Q5:动态序列帧可以做任何想要效果。也就是定义成一个图片,可以像普通图片一样调用。

Q6:脚本文件格式是rpy,只要在工程game文件夹里,rpy文件都能被renpy读取使用,无论rpy是什么文件名。

比如,定义的的图片,样式,只要知道图片名和样式名,你些的任何screen都可以调用此图片或样式,无论图片和样式在那个rpy文件里定义的。
不管建议就近定义,比如你做了一个screen对此screen使用的样式和使用到图片的定义,就在写在此screen上下处,便于就近找到调节修改(字体大小,颜色等),测试效果。
你也可以进行分门别类,你新建工程, 就进行分类,script.rpy是放剧情、option.rpy是游戏设置 、gui.rpy是GUI(图形用户接口)、 screen.rpy和界面有




回复 支持 1 抱歉 0

使用道具 举报

 楼主| 发表于 2019-7-27 01:01:53 | 显示全部楼层
Q2:这里希望实现的按钮效果是:每次只能选择一个部件,并弹出选择框,当玩家点选其他部件按钮时,当前按钮回归到idle状态。请问要如何才能做出这个效果?(目前点选后就只能一直保持开启状态了)


↑关于Q2已经解决了! 把facechoice、hairchoice、topchoice去掉,改用同一个变量,例如 openpart = 0
设置部件选择按钮的action为改变openpart,=1、=2、=3……
因为条件冲突自然就只能存在一个被选择的按钮了orz..
没想到这么简单(


-------------------------------------------------------

所以问题改问:SetVariable可以同时设置多个变量吗?,和SetScreenVaribale相比,两者用起来有什么区别?
(再次鞠躬)
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2019-7-27 01:08:19 | 显示全部楼层
另,关于注释里提到的“init:”用法以及和“init python:”的区别,因为刚在文档中看到“init -10 python:”的用法
所以我的理解是:
“init:”表示初始化设置,模块会在程式最初加载
“init python:”只是表示该初始化模块是直接用python语法写的
“-10”的部分是初始化优先级,数越小则优先级越高(所以默认是0?)
大概这样对吗?

评分

参与人数 1干货 +1 收起 理由
BuErShen + 1 版区有你更精彩(*^_^*)

查看全部评分

回复 支持 抱歉

使用道具 举报

发表于 2019-7-28 08:54:19 | 显示全部楼层
鼠西 发表于 2019-7-27 01:08
另,关于注释里提到的“init:”用法以及和“init python:”的区别,因为刚在文档中看到“init -10 python: ...

理解能力不错
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2019-8-3 23:07:15 | 显示全部楼层
BuErShen 发表于 2019-7-28 10:35
Q1:看你上传示意图,建议用层叠式图像(layeredimage),游戏开始renpy会初始化,层叠式图像(layeredimag ...

呜呜呜,以为会被嫌弃没想到版主这么认真回复了,非常感谢!!我明天就去实践一下看看!
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2019-8-5 10:18:51 | 显示全部楼层
BuErShen 发表于 2019-7-28 08:52
可以,用英文逗号“,”隔开。
SetScreenVariable是与screen相关变量赋值,相对于局部变量与全局变量。
...

这个试了一下发现按改名字按钮显示不会有任何变化(无论是不是screenvariable)...并且按钮按下去之后就永久开启弹不回来
删掉default后,setvariable就可以运作,screen还是不行_(:з」∠)_……
这是怎么回事
回复 支持 抱歉

使用道具 举报

发表于 2019-8-5 18:01:16 | 显示全部楼层
鼠西 发表于 2019-8-5 10:18
这个试了一下发现按改名字按钮显示不会有任何变化(无论是不是screenvariable)...并且按钮按下去之后就 ...

不太明白你的意思。
理论上按钮可以不断的点按,去执行某动作(action),除非你对这按钮用了 sensitive特性。
还有要区分:按钮(button)图片按钮(imagebutton)文本按钮(textbutton)


回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2019-8-6 13:42:10 | 显示全部楼层
BuErShen 发表于 2019-8-5 18:01
不太明白你的意思。
理论上按钮可以不断的点按,去执行某动作(action),除非你对这按钮用了 sensitive特 ...

之前不知怎么的,点击“aaa更改名字”和“bbb更改名字”按钮不会产生任何响应,只有HP会受到影响
再次试了一下发现又能正常运作了...感谢解答

总之就是:
如果存在相同名称的变量,setscreenvariable只会影响当前screen内的而不会干涉到外部,setvaribale会影响所有同样名称(相同地址?)的变量
回复 支持 抱歉

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 05:11 , Processed in 0.043144 second(s), 18 queries , File On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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