5.2 Wachten met async en await
Op deze pagina komen drie dingen samen. Twee daarvan ken je al, één is nieuw:
- In 5.1 Wachten in je spel zag je dat
time.sleep()het hele spel bevriest. - In 4.3 De muis gebruiken heb je
@play.when_mouse_clickedgezien. - Nieuw: de sleutelwoorden
asyncenawait. Daar gaat deze pagina over.
Lees rustig — als de muis-decorator je nog niet helemaal duidelijk is, kijk dan eerst even terug naar 4.3.
Ok, time.sleep() werkte niet. We hebben een manier nodig om een functie te laten wachten, terwijl de rest van het spel gewoon doorgaat. Hiervoor gebruiken we twee nieuwe sleutelwoorden: async en await.
Het idee is simpel:
- Met
asyncvertel je Python: "deze functie mag even wachten" - Met
awaitvertel je Python: "wacht hier even, maar laat de rest van het spel doorgaan"
Bekijk de code hieronder. Wat is er anders dan de time.sleep() versie van de vorige pagina?
Klik hier voor het antwoord.
Er zijn twee veranderingen:
defis veranderd inasync deftime.sleep(1)is veranderd inawait play.timer(seconds=1)
Hoe werkt dit precies?
import play
bal = play.new_circle(color='black')
bal.start_physics(obeys_gravity=False, x_speed=10)
@play.when_mouse_clicked
async def tijdelijk_sneller():
bal.physics.x_speed = 100
await play.timer(seconds=1)
bal.physics.x_speed = 10
- Regel 3-4: De bal, en de fysica die hem met snelheid 10 naar rechts stuurt.
- Regel 6: Koppelt de functie eronder aan een muisklik.
- Regel 7: Hier staat async voor
def. Daarmee mag deze functie wachten zonder het spel te pauzeren. - Regel 8: De bal gaat tien keer zo snel.
- Regel 9: await wacht één seconde. Dit is het verschil met
time.sleep(): alleen deze functie staat stil, het spel draait door. - Regel 10: Na die seconde gaat de snelheid terug naar 10.
Er gaat iets mis?
Een veelgemaakte fout is await gebruiken zonder async:
# FOUT - await kan alleen in een async functie
@play.when_mouse_clicked
def tijdelijk_sneller():
await play.timer(seconds=1)
De foutmelding die je krijgt:
SyntaxError: 'await' outside function
De oplossing: voeg async toe voor def.
Een andere fout is play.timer gebruiken zonder await:
# FOUT - play.timer zonder await doet niets
async def tijdelijk_sneller():
play.timer(seconds=1)
Dit geeft geen foutmelding, maar de timer wordt genegeerd. Je moet altijd await ervoor zetten.
Samengevat
| Sleutelwoord | Wat doet het? |
|---|---|
async | Zet je voor def. Hiermee mag de functie wachten zonder het spel te pauzeren. |
await | Wacht op iets (zoals een timer). Kan alleen in een async functie. |
Onthoud: async en await horen altijd bij elkaar. Als je await gebruikt, moet de functie async zijn.
Opdracht 5.2.a: Knipperend vierkant
Maak een vierkant dat bij een muisklik 3 keer knippert (zichtbaar → onzichtbaar → zichtbaar) en dan weer normaal is.
Klik hier voor een tip.
Gebruik hide() en show() met await play.timer(seconds=0.3) ertussen.
Klik hier voor de oplossing.
Opdracht 5.2.b: Tijdelijke kleurverandering
Maak een cirkel die:
- Normaal blauw is
- Bij het indrukken van spatie rood wordt
- Na 2 seconden weer blauw wordt
Klik hier voor een tip.
Dit zijn drie regels in één functie: kleur veranderen, wachten, kleur terugzetten. Denk aan async voor def, anders mag je niet wachten.