RenPy中文空间

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5964|回复: 9

[已解决] 自己写了一个计算时间的类实例方法,但是输出出现了问题

[复制链接]
发表于 2021-6-23 20:57:57 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Zealot001 于 2021-6-24 09:44 编辑

[RenPy] 纯文本查看 复制代码
default timekey = 0
default timer =thetimes(timeskey)
init -1 python:
    period = ["早晨", "上午", "下午", "晚上"]

    class thetimes:
        def __init__(self,timedata):
            self.timedata = timedata

        @property
        def timepassing(self):
            self.timedata += 1
            return self.period[self.timedata]

screen virtue():
        text "{size=100}时间: [timer.timepassing] {/size}"

最后输出的结果并不是列表中的元素,而是无法识别,游戏直接显示是timer.timepassing,
如果把代码更换一下
直接在类实例方法中
return self.timedata
又可以输出数值,比如初始化0,他这里会输出2
这里也有一点奇怪的是,按理说+=1,这个类方法只执行一次,但是实际游戏里,每次被调用,数值会增加2,也就是说,类方法被执行了两次
请教大神指出其中的错误。
发表于 2021-6-24 00:12:16 | 显示全部楼层
原因在于Ren'Py的screen会预加载,在预加载阶段内,screen内的代码可能会被多次执行。
验证用例:
[RenPy] 纯文本查看 复制代码
init -1 python:
    class Counter(object):
        def __init__(self):
            self.counter = 0

        @property
        def count(self):
            self.counter += 1
            print(self.counter)
            return self.counter

default screen_counter = Counter()
default label_counter = Counter()

define black = Solid("#000")

label main_menu:
    pass

label start:
    scene black
    while True:
        show screen test
        "label counter: [label_counter.count]"
        hide screen test

screen test():
    text "screen counter: [screen_counter.count]"


可以发现,每次界面显示与重绘时,screen 中的计数器都会增加(比如Ctrl+O进入控制台并退出),而 label 中(say 语句中)的计数器只有显示时才会增加。

由于界面预加载的特性,在界面中使用产生副作用的代码往往无法预期产生的结果。在界面中使用的函数必须是纯函数,也就是说,给定相同的输入,一定会得到相同的输出。


对于问题中的代码,可以把 timepassing 中产生副作用的部分拆分出来,在 show screen 之前执行。
[RenPy] 纯文本查看 复制代码
init -1 python:
    class thetimes:
        period = ["早晨", "上午", "下午", "晚上"]
        def __init__(self, timedata):
            self.timedata = timedata
 
        def timepassing(self):
            self.timedata += 1

        @property
        def time(self):
            return self.period[self.timedata]

default timer = thetimes(0)
label start:
    $ timer.timepassing()
    show screen virtue

screen virtue():
    text "{size=100}时间: [timer.time] {/size}"


回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2021-6-23 21:39:44 | 显示全部楼层
刚才自己测试了好几次,彻底糊涂了
label标签执行一次,label语句块里的语句应该全部执行一遍,但测试的是,类方法被被多次调用。
具体原因求解答
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-24 08:24:04 | 显示全部楼层
忘忧北萱草 发表于 2021-6-24 00:12
原因在于Ren'Py的screen会预加载,在预加载阶段内,screen内的代码可能会被多次执行。
验证用例:
[mw_shl_ ...

谢谢解答,晚上回去测试一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-24 08:28:23 | 显示全部楼层
忘忧北萱草 发表于 2021-6-24 00:12
原因在于Ren'Py的screen会预加载,在预加载阶段内,screen内的代码可能会被多次执行。
验证用例:
[mw_shl_ ...

另外,大佬,列表的显示问题应该怎么解决,我自己用list[0]可以正常输出list中的0号元素,但是让n=0,list[n]就无法正确输出了,renpy不会报错,但输出的是"list[n]"
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-24 09:15:30 | 显示全部楼层
忘忧北萱草 发表于 2021-6-24 00:12
原因在于Ren'Py的screen会预加载,在预加载阶段内,screen内的代码可能会被多次执行。
验证用例:
[mw_shl_ ...

刚才实验了一下,再设定一个var,把类实例里面的值返回到var里面,然后直接显示var,既可以避免重复调用,又可以正确显示数值了

default currentTime = timer.timepassing
label xxx:
...
$ currentTime = timer.timepassing
...
回复 支持 反对

使用道具 举报

发表于 2021-6-24 09:16:44 | 显示全部楼层
Zealot001 发表于 2021-6-24 08:28
另外,大佬,列表的显示问题应该怎么解决,我自己用list[0]可以正常输出list中的0号元素,但是让n=0,lis ...

具体代码发出来看看……

另外,thetimes类的timepassing返回结果最好修改一下,避免下标越界报错:
[RenPy] 纯文本查看 复制代码
return period[self.timedata % 4]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-24 10:02:42 | 显示全部楼层
被诅咒的章鱼 发表于 2021-6-24 09:16
具体代码发出来看看……

另外,thetimes类的timepassing返回结果最好修改一下,避免下标越界报错:

嗯嗯,我知道会越界,测试成功后已经改了
另外list显示问题,确实让人摸不着头脑
[RenPy] 纯文本查看 复制代码
default list110 = ["早晨", "上午", "下午", "晚上"]
default n = 0
screen virtue():
    text "{size=20}时间: [list[n]] {/size}"

如果直接用list[0],就可以正确显示,但是如果用list[n]就不行

回复 支持 反对

使用道具 举报

发表于 2021-6-24 21:18:14 | 显示全部楼层
Zealot001 发表于 2021-6-24 10:02
嗯嗯,我知道会越界,测试成功后已经改了
另外list显示问题,确实让人摸不着头脑
[mw_shl_code=renpy,tru ...

text这句定义了文本组件,只支持文本插值(text interpolation)。如字面意思,所有变量经过文本插值后都是字符串类型,list[n]中的n经过插值也会变成字符(串)。
所以,只能通过某个变量传递数组元素。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-25 08:23:53 | 显示全部楼层
被诅咒的章鱼 发表于 2021-6-24 21:18
text这句定义了文本组件,只支持文本插值(text interpolation)。如字面意思,所有变量经过文本插值后都是 ...

原来如此,谢谢解答!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2022-6-26 07:37 , Processed in 0.025173 second(s), 13 queries , File On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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