The drifting animation in such task must be done in fixed time steps. While rendering of animation frames can naturally scripted in the Control Loop snippet, the control the frame times is not so easy, since rendering needs to be synchronized with monitor frames.
I would recommend to use a better approach by turning a recurrent event to a pacer for animation frames. To turn an event to the animation pacer you need to:
- Add the recurrent time route to the event
- Add animated stimuli in this event (for this case, 2 gratings)
- Set the "Live rendering" property of the event to 'false' to prevent immediate visual updates
- Implement the grating animation in 'After onset' snippet of the pacer event. Since event's live rendering is off, the visual changes on gratings will be presented only on the next event onset.
- Finally, set the animation frame time by the duration of the pacer event. The duration of the pacer event has to be greater, than the frame rendering time. You can measure the actual rendering time for 2 gratings with the profiler.
To demonstrate this approach, I uploaded a 2AFC task here:
Note that the pacer event is located on the sub-layer of the Stimulus&Response event, which handles participant responses, while the pacer sub-event runs the animation at 60hz. The temporal frequency of gratings is defined by a phase shift for 1 animation frame.