我正在努力理解如何控制Shady在屏幕上绘制的内容流。我习惯了Psychtoolbox,在这里,通过在backbuffer上绘制来不断添加到帧中,然后通过调用flip()显式地将其推到屏幕上。有了阴影,事情似乎会自动发生,所以当你向一个世界添加一个刺激对象时,它会很快被绘制出来。但是,如果我必须添加几个刺激,我怎么能保证屏幕上没有更新,直到他们都被画出来
例如,假设我想画一个空白屏幕,在它的左上角画一个小正方形。我可以这样做:
w = Shady.World()
s1 = w.Stimulus(None, 'blank', envelopeSize=[1920, 1200], backgroundColor=[0, 0, 0], z=0)
s2 = w.Stimulus(None, 'square', envelopeSize=[20, 20], x=-950, y=590, backgroundColor=[1, 1, 1], z=1)
但是我怎么能保证我不会从n帧开始画s1,从n+1帧开始画s2呢?也许它们可以组合成一个刺激对象,但我想把它们分开(在我的实际问题中,小正方形实际上是用来触发一个光电管的,所以我需要能够在任务中的不同时间闪烁一帧)
首先,阅读Concurrency上的可疑文档是个好主意。前两个示例(在标题“Running single threaded”下)没有您担心的问题,因为
Stimulus
实例是在实际渲染单个帧之前创建的。下面是一个简单的例子:除此之外,Shady固有的范式转变之一就是你自己从不称任何
flip()
等价物。一开始可能会觉得不熟悉,但请放心:在我们基于Shady构建的应用程序中,我们不会错过自己调用flip()
的日子。在回调中更新刺激参数,例如:所谓的“动画回调”,您可以选择安装到每个
World
或Stimulus
实例中动态(可调用)值,可以分配给任何
World
或Stimulus
属性(在任何动画回调之后立即计算这些值)响应按键等的事件回调。
在同一回调中所做的更改保证在同一帧上呈现,这就是我们如何严格控制计时的答案,即使不运行单线程。确实,如果运行多线程并发出一个接一个的
w.Stimulus()
调用,它们就不能保证出现在同一帧上(事实上,它们一定会出现在不同的帧上,因为非绘制线程中的.Stimulus()
调用实际上会将实际的刺激创建工作延迟到绘制线程中,然后等待直到完成后才返回)。可能的解毒剂是(1)运行单线程(2) 在专用的Prepare()
方法中执行所有w.Stimulus()
创建调用,如文档的第二个示例所示;或者(3)确保刺激物在创建时有visible=False
,并且只在以后可见。在所有这些情况下,我们都会小心地将刺激物的产生(可能很慢)与对刺激物性质的操纵分开前两种回调类型与您所描述的内容最相关。Shady在"Making properties dynamic"上的文档中介绍了它们。在它们提供的框架中,有许多不同的方法(在Python和Shady中都是这样)来实现您描述的目标。我个人喜欢使用^{} 实例作为动画回调。下面是我如何创建一个简单的重复呈现的刺激,它的开始是由一个传感器补丁在一帧中闪烁所预示的:
相关问题 更多 >
编程相关推荐