'Traffic light turtle python
I am having some trouble with making my program wait for the user key, spacebar, to begin the program. I have to build a Python program using turtle graphics to simulate a traffic light where the program starts execution with a blank screen. Also create a keypress event ("space") and handler to draw a stop light with a green light and an event handler with a timer event that goes off in 5 seconds. Here is what I have. anyone have any suggestions?
import turtle
wn = turtle.Screen()
wn.title("traffic light")
wn.bgcolor("sky blue")
def draw_housing():
house = turtle.Turtle()
house.pensize(3)
house.color("black", "darkgrey")
house.begin_fill()
house.forward(80)
house.left(90)
house.forward(200)
house.circle(40, 180)
house.forward(200)
house.left(90)
house.end_fill()
def draw_post():
post = turtle.Turtle()
post.pensize(3)
post.color("black")
post.penup()
post.goto(50,0)
post.pendown()
post.begin_fill()
for i in range(2):
post.right(90)
post.forward(80)
post.right(90)
post.forward(25)
post.end_fill()
# This function will draw 3 black lights which will work as off signal lights
def draw_off_lights():
distance = 50
for i in range(3):
off_turtle = turtle.Turtle()
off_turtle.speed(0)
off_turtle.penup()
off_turtle.forward(40)
off_turtle.left(90)
off_turtle.forward(distance)
off_turtle.shape("circle")
off_turtle.shapesize(3)
off_turtle.fillcolor("white")
distance+=70
draw_post()
draw_housing()
draw_off_lights()
light = turtle.Turtle()
light.penup()
# Position first onto the place where the green light should be
light.forward(40)
light.left(90)
light.forward(50)
light.shape('circle')
light.shapesize(3)
light.fillcolor('green')
# This variable holds the current state of the machine
state_num = 0
def state_machine():
global state_num
if state_num == 0: # Transition from state 0 to state 1
state_num = 1
light.forward(70)
light.fillcolor('yellow')
wn.ontimer(state_machine, '2000')
elif state_num == 1: # Transition from state 1 to state 2
state_num = 2
light.forward(70)
light.fillcolor('red')
wn.ontimer(state_machine, '5000')
else: # Transition from state 2 to state 0
state_num = 0
light.back(140)
light.fillcolor('green')
wn.ontimer(state_machine, '5000')
state_machine()
wn.onkey(draw_post, 'space')
wn.listen
wn.mainloop()
Solution 1:[1]
Below is my rework of your code that addresse issues discussed (listen(), bundling calls to drawing functions into one handler that is triggered by onkey, state_num not defined) It also addresses some other issues you might find of use and tries to simplifies the code by making the drawing centered on the window instead of just right of center:
from turtle import Screen, Turtle
DISTANCE = 70
def draw_housing():
housing.begin_fill()
housing.forward(40)
housing.left(90)
housing.forward(200)
housing.circle(40, 180)
housing.forward(200)
housing.left(90)
housing.forward(40)
housing.end_fill()
def draw_post():
post.begin_fill()
for _ in range(2):
post.forward(12.5)
post.right(90)
post.forward(80)
post.right(90)
post.forward(12.5)
post.end_fill()
# This function will draw 3 black lights which will work as off signal lights
def draw_off_lights():
off_turtle.forward(50)
for _ in range(3):
off_turtle.stamp()
off_turtle.forward(DISTANCE)
def user_started():
screen.onkey(None, 'space') # prevent double activation
draw_post()
draw_housing()
draw_off_lights()
# Position first onto the place where the green light should be
light.forward(50 + DISTANCE*2)
light.showturtle()
state_machine()
screen = Screen()
screen.title("traffic light")
screen.bgcolor("sky blue")
housing = Turtle()
housing.hideturtle()
housing.pensize(3)
housing.fillcolor("darkgrey")
post = Turtle()
post.hideturtle()
post.pensize(3)
off_turtle = Turtle()
off_turtle.hideturtle()
off_turtle.shape("circle")
off_turtle.shapesize(3)
off_turtle.penup()
off_turtle.setheading(90)
light = off_turtle.clone()
light.fillcolor('green')
# This variable holds the current state of the machine
state_num = 2
def state_machine():
global state_num
if state_num == 0: # Transition from state 0 to state 1
state_num = 1
light.forward(DISTANCE)
light.fillcolor('yellow')
screen.ontimer(state_machine, 2000)
elif state_num == 1: # Transition from state 1 to state 2
state_num = 2
light.forward(DISTANCE)
light.fillcolor('red')
screen.ontimer(state_machine, 5000)
else: # Transition from state 2 to state 0
state_num = 0
light.back(DISTANCE*2)
light.fillcolor('green')
screen.ontimer(state_machine, 5000)
screen.onkey(user_started, 'space')
screen.listen()
screen.mainloop()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
