psychopy.org | Reference | Downloads | Github

Skipped Frames in Animation

Hi All,

I’m coding a visual illusion that is supposed to flash a black window for 5 frames and one black bar per frame following. However, the illusion is not running correctly as the animation is skipping frames. The frame rate of the illusion is supposed to match the frame rate of most monitors, 60 hz, however it is running at 30 Hz and I’m not sure why. Any help is greatly appreciated. My code is below.

import math, random
from psychopy import visual, core, event, gui


#creates window
myWin = visual.Window(color = 'white', units = 'pix', size = [1000,1000], allowGUI = False, fullscr = False)

#creates and starts a clock to read later
myClock = core.Clock()

#dimensions of rectangles
movingRect = visual.Rect(myWin, width = 25, height = 400, fillColor = 'black', lineColor = None)

#position of first bar
movingRect.setPos([-200,0])

#make entire screen black
blackRect = visual.Rect(myWin, width = 1000, height = 1000, fillColor = 'black', lineColor = None)

#set for 60 Hz monitors
frameRate = 0.0167

myWin.recordFrameIntervals = True

def mainLoop():

    finished = False

    while not finished:
    
        movingRect.draw()
        movingRect.setPos([100,0], operation = "+")
        y = movingRect.pos[0]
    
    
        if y == 400:
            blackRect.draw()
            movingRect.setPos([-200,0])
            myWin.flip()
            frameRateB = frameRate * 5
            speed = frameRateB
            speed = frameRate
        
        else:
            myWin.flip()
            speed = frameRate 
    
    
        #key controls
        if event.getKeys(keyList = ['escape']):
            finished = True
   
    
   
        waitUntil = myClock.getTime() + speed
        while myClock.getTime() < waitUntil:
            pass 
    

    
    
        
mainLoop()
myWin.close()
core.quit()

It’s drawing at 30 Hz because your code is telling it to.

i.e. by pausing for approximately 16.7 ms after each win.flip(), you will almost guarantee missing the next screen refresh. If you want frame-specific timing, then don’t use any timers. Let win.flip() do the work for you automatically to get 60 Hz drawing. i.e. you should be drawing on every screen refresh, even if the stimuli are unchanging, and not inserting any timer-based pauses. By using win.flip(), you harness the hardware refresh cycle in a way that you can’t hope to do using software timers.

Perhaps you need to look through some of the coder demos some more to get a feeling for how this works.

This fixed it, thanks!!