Search code examples
pythonanimationpyglet

Pyglet animation: stop it after a certain time and load new parameters


I am working on a python scripts that load some values from a text file and uses them as the parameters of an animation. I want to display a series of animations with a menu between them that waits for user interaction.

I would like to know how to stop the animation within an established time, and then load new parameters for a second animation, but without closing the window that displayed the first animation.

The code I use is the following:

## Create pyglet window
# Get screens
screens = pyglet.window.get_platform().get_default_display().get_screens()

config = pyglet.gl.Config(stencil_size=8)

# Create window
myWindow = pyglet.window.Window(config=config,fullscreen=True,screen=screens[0])


## Functions definition

def ConfigFileToStruct(configfilename):
#Loads the configuration file to a pydic

@myWindow.event
def on_mouse_press(x, y, button, modifiers):

@myWindow.event
def on_mouse_release(x, y, button, modifiers):

@myWindow.event
def on_close():

def drawCircle(radius, circle_color, x, y):

def drawGrating(x, y, fill_color, orientation, mylambda, duty_cycle):

def update_frames(dt):
    global x1, x2, apertRad_pix, speed1, speed2, timeStart, mylambda1, mylambda2

    timeNow = time.clock()
    motion_cycle1 = mylambda1/(math.cos(math.radians(orientation1)))
    motion_cycle2 = mylambda2/(math.cos(math.radians(orientation2)))


    initialpos1 = myWindow.width/2 - apertRad_pix - mylambda1/2
    initialpos2 = myWindow.width/2 - apertRad_pix + mylambda2/2

    # update position of grating 1:
    x1 = initialpos1 + math.fmod(speed1*(timeNow-timeStart), motion_cycle1)

    # update position of grating 2:
    x2 = initialpos2 + math.fmod(speed2*(timeNow-timeStart), motion_cycle2)


@myWindow.event
def on_draw():

    #Define variables
    Red = (1.0, 0.88, 0.88, 0.5)
    Cyan = (0.88, 1.0, 1.0, 0.5)

    glEnable(GL_BLEND)
    pyglet.gl.glClearColor( 0.6, 0.6, 0.6, 0 )
    myWindow.clear()

    # Enable stencil
    glClearStencil(0x0)
    glEnable(GL_STENCIL_TEST) 

    #define the region where the stencil is 1
    glClear(GL_STENCIL_BUFFER_BIT)
    glStencilFunc(GL_ALWAYS, 0x1, 0x1)
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)

    # draw Fixation point

    drawCircle(apertRad_pix/15, [0, 0, 0],       x0_pix, y0_pix)
    drawCircle(apertRad_pix/80, [0.9, 0.9, 0.9], x0_pix, y0_pix)

    stereo1 = -1

    drawGrating(x1 + stereo1, y1, Cyan, orientation1, mylambda1, duty_cycle1)
    drawGrating(x1 - stereo1, y1, Red, orientation1, mylambda1, duty_cycle1)

    glBlendFunc(GL_ONE, GL_ZERO)


## Main
if __name__ == "__main__":
    namefile = "cfgfile.txt"

    # Load configuration parameters
    config = ConfigFileToStruct(namefile)
    if not config:
        print("CONFIG FILE EMPTY")
    else:
        print("CONFIG FILE LOADED")

    # VARIABLES       
    apertRad_pix = 400

    ## GRATING PARAMETERS
    #grating1
    x1 = x0_pix - apertRad_pix
    y1 = y0_pix - apertRad_pix

    mylambda1 = config["gratings1"]["wavelength"]
    duty_cycle1 = config["gratings1"]["duty_cycle"]
    orientation1 = config["gratings1"]["orientation"]
    speed_pix = config["gratings1"]["speed"]
    speed1 = speed_pix / math.cos(math.radians(orientation1))       

    ## Run stimulus   
    timeStart = time.clock()    

    framerate = 1/60.0


    pyglet.clock.schedule_interval(update_frames,framerate)


    pyglet.app.run()

Solution

  • Stepping through the scenario text file parameters should actually be part of the update function of your animation :

    • use for instance a while elapsed_time < current_sequence_time_limit loop inside update_frames(dt)

    • make the "load configuration" code part from the main a separate function (to make a cleaner code) and call it from update_frames(dt) every time the while loop exits