原因在于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}"
|