我正在尝试使用Shady来呈现一系列图像帧。在过去,我通过给stimulus.page属性分配一个动画回调来做到这一点。在回调中,Shady为每个监视器帧调用一次,我首先检查一个全局变量,该变量跟踪应该显示哪个刺激帧。如果它是正的,我将刺激的可见性设置为True并返回帧编号;否则我将其设置为False并返回0。就像一种护身符。
现在我需要扩展它,因为我需要从多个序列中选择一个来显示。由于加载序列可能需要一些时间,因此我在程序开始时加载它们,并将每个序列与一个刺激对象相关联。现在,这是我的问题。我是否必须为每个序列创建不同的动画回调函数(其数量是可变的,并且可以是高的)。或者,有没有一种更好的方法来调用单个动画回调(或类似的回调),并在其中确定要显示哪个序列的哪个帧(同样,基于全局变量的当前值)?
发布于 2020-02-12 02:08:14
首先,我想确认“动画回调”和“动态属性值”在术语上的区别。Shady文档,以及这个答案,并没有提到你正在使用的“动画回调”。但我认为,对你的问题最好的答案可能是使用实际的动画回调。
World和Stimulus实例的某些属性分配可调用对象。如果是这样,则在每一帧上调用它们。您的stimulus.page就是一个这样的例子(尽管page不是一个成熟的“托管属性”,也就是说,它具有与另一个实例的相应属性共享内存的能力,但它确实以这种方式支持“动态分配”)。如果一次只想更改几个刺激的几个方面,并且/或者希望一个属性中的更改完全独立于另一个属性中的更改,则动态属性是很好的。动态分配的函数必须只有一个参数-时间t (以秒为单位)-但(根据您的注释)这确实允许您使用具有原型blah(self, t)的s (或者实际上是任何其他实例)的已绑定方法,因为当您访问它时,self将被烘焙。该函数还必须返回一个值-应该分配给此frame.Stimulus实例s (以及另外的World实例)都有一个“动画回调”,该回调占用属性槽s.Animate,并且可以通过s.SetAnimationCallback方法或其等效函数装饰器@s.AnimationCallback进行更改。在每个帧上,每个World或Stimulus实例都会检查它是否有.Animate属性,如果有,就调用它。如果您希望对多个属性(例如,s.visible和s.page)的更改彼此协调,那么附加到s的动画回调可能是实现此目的的最佳位置。与动力学不同,动画回调可以是一个(未绑定的)方法,它将s的引用作为self接收,因此self的属性可以用作“全局”(但特定于刺激实例的)便签簿。(实际上,对于动画回调,您可以选择是使用类似于方法的原型blah(self, t)来定义它们,还是使用类似于动态的单参数原型blah(t)来定义它们。)在动态是函数式的情况下,动画回调是过程性的:忽略动画回调的任何返回参数。在任何一种情况下,您附加回调的所有刺激都将调用它,并且所有刺激都将在每一帧上调用其动态,而不检查其他实例是否也在使用相同的可计算,这是事实(正如您担心的那样)。如果您希望确保代码不会被不必要地调用,您的选择包括:
Stimulus可见:让每个Stimulus在其自己的动画回调和/或其动态属性(以对您最有意义的为准)中遵循其自己的逻辑。但是,当它应该在屏幕之外时,不要只设置s.visible = False:相反,实际上应该让Stimulus实例s.Leave()舞台,并在必要时再次设置s.Enter()。当您在舞台上时,即使您是不可见的,您的动画回调和动力学也会在每一帧上调用。当你在台下时,它们不会被调用。在python -m Shady demo sharingWorld动画回调,因为只有一个World,所以每帧肯定只调用一次。对单个刺激的引用始终可以作为全局变量检索,也可以通过名称从self.stimuli容器中检索:导入Shady cmdline = Shady.WorldConstructorCommandLine() cmdline.Help().Finalize() w= Shady.World( **cmdline.opts ) w.Stimulus( name='bill',x=-100,size=100,color=1,0,0 ) w.Stimulus( name='ben',x=+100,size=100,color=0,0,1 ) @w.AnimationCallback def Animate( self,t ):#自上而下控制多个刺激:如果self.framesCompleted % 2:# self.stimuli是一个字典,具有所有预期的字典功能...Self.timuli‘’bill‘.Visible= True self.expli’‘ben’.Visible= False否则:# ...but它也支持延迟语法: self.stimuli.bill.visible = False self.stimuli.ben.visible = True Shady.AutoFinish( W )
https://stackoverflow.com/questions/60174129
复制相似问题