Start and stop Python turtle with space bar (wall design)

Viewed 60

The program draws the layout of the wall. According to my idea, it should draw the boundaries of the wall, move to the center and only when pressing the spacebar fill the wall with drawings, creating a design. And it should also stop when the spacebar is pressed. The problem is that with my code, it performs all tasks, except for stopping. Do you have any ideas? The picture shows the result.result The program works with files that contain color palettes.

from turtle import *
from turtle import Screen
from random import randint
import random

seinalaius=float(input("Sisestage seina laius (500-1500): "))
seinapikkus=float(input("Sisestage seina pikkus (500-900): "))
värvipalett=input("Mis värvipaletti tahaksite kasutada? (Valik: mustvalge, roosa, punane, lilla, sinine, kollane, roheline, beež, oranž): ")
screen = Screen()
fail = open(värvipalett + '.txt', encoding='UTF-8')
värvid = []
for rida in fail:
    rida = rida.strip()
    värvid.append(rida)

up()
goto(-seinalaius / 2, -seinapikkus / 2)
down()

for i in range(2):
    forward(seinalaius)
    left(90)
    forward(seinapikkus)
    left(90)

up()
goto(0, 0)
down()

def current_state():
        global moving
        moving = False
        penup()

def next_state():
    global moving
    pendown()
    moving = True
    move()

def space_bar():
    global current_state, next_state
    next_state()
    current_state, next_state = next_state, current_state

def move():
    if moving:
        while True:
            pöörded = randint(4, 8)
            begin_fill()
            color(random.choice(värvid))
            for i in range(pöörded):
                pikkus = randint(0, 150)

                up()
                forward(pikkus)
                if not -seinalaius / 2 <= xcor() <= seinalaius / 2 or not -seinapikkus / 2 <= ycor() <= seinapikkus / 2:
                    backward(pikkus)
                backward(pikkus)
                down()

                forward(pikkus)
                lr = randint(1, 2)
                if lr == 1:
                    left(90)
                else:
                    right(90)
            speed("fastest")
            end_fill()
            up()
            down()

current_state()

screen.onkey(space_bar, "space")

screen.listen()

screen.mainloop()

File ('sinine.txt') content:

aliceblue
aquamarine
aquamarine1
aquamarine2
aquamarine3
aquamarine4
blue
blue1
blue2
blue3
blue4
CadetBlue
CadetBlue1
CadetBlue2
CadetBlue3
CadetBlue4
CornflowerBlue
cyan
cyan1
cyan2
cyan3
cyan4
DarkBlue
DarkCyan
DarkSlateBlue
DarkSlateGray
DarkSlateGray
DarkSlateGray2
DarkSlateGray3
DarkSlateGray4
DarkSlateGrey
DarkTurquoise
DeepSkyBlue
DeepSkyBlue2
DeepSkyBlue3
DeepSkyBlue4
DodgerBlue
DodgerBlue1
DodgerBlue2
DodgerBlue3
DodgerBlue4
LightBlue
LightBlue1
LightBlue2
LightBlue3
LightBlue4
LightSeaGreen
LightSkyBlue
LightSkyBlue1
LightSkyBlue2
LightSkyBlue3
LightSkyBlue4
LightSlateGray
LightSlateGrey
LightSteelBlue
LightSteelBlue1
LightSteelBlue2
LightSteelBlue3
LightSteelBlue4
MediumAquamarine
MediumBlue
MediumSlateBlue
MediumTurquoise
midnightblue
MidnightBlue
navy
NavyBlue
PaleTurquoise
PaleTurquoise1
PaleTurquoise2
PaleTurquoise3
PaleTurquoise4
PaleVioletRed
PowderBlue
RoyalBlue
RoyalBlue1
RoyalBlue2
RoyalBlue3
RoyalBlue4
SkyBlue
SkyBlue1
SkyBlue2
SkyBlue3
SkyBlue4
SlateGray
SlateGray1
SlateGray2
SlateGray3
SlateGray4
SteelBlue
SteelBlue1
SteelBlue2
SteelBlue3
SteelBlue4
turquoise
turquoise1
turquoise2
turquoise3
turquoise4
1 Answers

Your state machine logic is a disaster. First, current_state and next_state are the names of both functions and variables! Don't do that, one overwrites the other. Next, you never initialize either of the above. The inner While True: loop in move() keeps the outer if moving: test from ever stopping the action. Your select_next_state() handler calls move() directly so effectively never returns.

I've reworked your code below to start and stop as you intended. I use ontimer() to fire off move() so the event handler can return immediately. I collapse the two loops in move() into one and initialize your global state variables. And cleaned up anything else that caught my eye:

from turtle import Screen, Turtle
from random import randint, choice

current_state, next_state = False, True
moving = current_state

def select_current_state():
    global moving

    moving = current_state

def select_next_state():
    global moving

    moving = next_state

    screen.ontimer(move)

def space_bar():
    global current_state, next_state

    select_next_state()

    current_state, next_state = next_state, current_state

def move():
    while moving:
        pöörded = randint(4, 8)
        turtle.color(choice(värvid))
        turtle.begin_fill()

        for _ in range(pöörded):
            pikkus = randint(0, 150)

            turtle.penup()
            turtle.forward(pikkus)
            if not -seinalaius / 2 <= turtle.xcor() <= seinalaius / 2 or not -seinapikkus / 2 <= turtle.ycor() <= seinapikkus / 2:
                turtle.backward(pikkus)
            turtle.backward(pikkus)
            turtle.pendown()

            turtle.forward(pikkus)

            if choice([True, False]):
                turtle.left(90)
            else:
                turtle.right(90)

        turtle.end_fill()

seinalaius = float(input("Sisestage seina laius (500-1500): "))
seinapikkus = float(input("Sisestage seina pikkus (500-900): "))

värvipalett = input("Mis värvipaletti tahaksite kasutada? (Valik: mustvalge, roosa, punane, lilla, sinine, kollane, roheline, beež, oranž): ")

fail = open(värvipalett + '.txt', encoding='UTF-8')

värvid = []

for rida in fail:
    rida = rida.strip()
    värvid.append(rida)

screen = Screen()

turtle = Turtle()
turtle.speed('fastest')

turtle.penup()
turtle.goto(-seinalaius / 2, -seinapikkus / 2)
turtle.pendown()

for _ in range(2):
    turtle.forward(seinalaius)
    turtle.left(90)
    turtle.forward(seinapikkus)
    turtle.left(90)

turtle.penup()
turtle.home()
turtle.pendown()

select_current_state()

screen.onkey(space_bar, 'space')

screen.listen()

screen.mainloop()
Related