Search code examples
pythonturtle-graphicspython-turtle

How do you make a conditional loop with onkeypress()?


I'm working on a python project for my intro class where I want to make a blizzard with the turtle module. So far, I've been able to make a "snowflake" appear on each keypress but I'm not sure how to make it into a conditional loop where when I click, it becomes true and keeps looping without me having to click again.

Here's the code I have right now:

def snowing(x, y):
        w.speed(0)
        flake_size = randint(1, 5)
        rx = randint(-250, 250)
        ry = randint(-300, 300)
        w.color(colours[5])
        w.setposition(rx, ry)
        w.pendown()
        w.begin_fill()
        w.circle(flake_size)
        w.end_fill()
        w.penup()
listen()
onscreenclick(snowing, add=None)

Solution

  • when I click, it becomes true and keeps looping without me having to click again.

    We can make a separate event handler that is a toggle, using a global to switch between on and off on subsequent clicks. We'll combine that with a timer event to keeps the flakes coming:

    from turtle import Screen, Turtle
    from random import randint, choice
    
    COLOURS = ['light gray', 'white', 'pink', 'light blue']
    
    is_snowing = False
    
    def toggle_snowing(x, y):
        global is_snowing
    
        if is_snowing := not is_snowing:
            screen.ontimer(drop_flake)
    
    def drop_flake():
        flake_radius = randint(1, 5)
    
        x = randint(-250, 250)
        y = randint(-300, 300)
    
        turtle.setposition(x, y)
        turtle.color(choice(COLOURS))
    
        turtle.begin_fill()
        turtle.circle(flake_radius)
        turtle.end_fill()
    
        if is_snowing:
            screen.ontimer(drop_flake)
    
    turtle = Turtle()
    turtle.hideturtle()
    turtle.speed('fastest')
    turtle.penup()
    
    screen = Screen()
    screen.setup(500, 600)
    screen.bgcolor('dark blue')
    screen.onclick(toggle_snowing)
    screen.listen()
    
    screen.mainloop()
    

    When you click on the screen, the flakes will start appearing. When you click again, they will stop.