logo CoderDojo

Python - Vuurwerk

Dit is de eerste dojo in het nieuwe jaar 2025 en we maken deze keer vuurwerk!

Happy new year

Bij oud en nieuw hoort vuurwerk, dus deze keer maken we zelf ons vuurwerk met Python en de Turtle-bibliotheek.

Deze instructie is vrij uitgebreid en maakt gebruik van technieken die onbekend zijn voor beginners. Maar als je de code goed kopiëert en plakt, dan moet het lukken iets werkends te krijgen zelfs als je niet meteen begrijpt hoe het werkt.
En vraag vooral de mentoren om hulp! 😉

Thonny installeren

We gebruiken voor deze instructie Thonny. Deze moet je installeren als je die nog niet hebt.
Heb je die al wel en weet je hoe je er mee om moet gaan, ga dan verder met het volgende hoofdstuk.

Downloaden

Thonny is beschikbaar vanaf Thonny.org voor Windows, MacOS en Linux.

Tijdens de dojo kun je het installatiebestand sneller downloaden van de CoderDojo server hier.

Installatie

Installeer het gedownloade bestand door het uit te voeren. Volg de instructies tijdens de installatie.

Gebruik

Thonny is misschien in het Engels, maar ondersteunt ook Nederlands.

Ga daarvoor in het menu naar “Tools” - “Options”. Op tab “General” vind je “Language” en kun je Nederlands kiezen. Je moet Thonny even opnieuw opstarten om de Nederlandse teksten te zien.

Thonny taal instellingen

🎆 Vuurwerk maken!

We beginnen met het maken van een vuurpijl die de lucht in schiet. Dat gaan we in stappen doen.

1. We maken een venster

Neem het volgende over in Thonny:

1
2
3
4
5
import turtle

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

Thonny scherm

Druk op het groene knopje (of F5) om het programma uit te proberen. Thonny uitvoerknop

Let op!

2. Maak een zwarte punt die later de vuurpijl wordt

1
2
3
4
5
6
7
8
import turtle

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

vuurpijl = turtle.Turtle()
vuurpijl.dot(5)

Voer het programma uit. Zie je de zwarte punt?

Opdrachten

  1. Pas één of beide getallen in venster.setup(800, 800) eens aan. Wat gebeurt er?
  2. Wat gebeurt er met de zwarte punt als je de 5 in vuurpijl.dot(5) verandert naar 10? Of naar 1?

3. De vuurpijl beweegt omhoog

Laten we eens kijken of we de punt naar boven kunnen laten bewegen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import turtle

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

vuurpijl = turtle.Turtle()
vuurpijl.dot(5)
vuurpijl.setposition(0, 50)
vuurpijl.dot(5)

Als je dit uitvoert, zie je twee punten met een dunne lijn er tussen.

Opdrachten

setposition betekent: doe iets op deze locatie. De twee getallen zijn de horizontale positie en de verticale positie. Het eerste getal is het aantal pixels rechts van het midden van het scherm en het tweede getal is het aantal pixels bóven het midden.

  1. Zet de punten eens rechts in het venster. Of juist links.
  2. Hoe kun je de positie van de punten omhoog of omlaag veranderen?

4. De vuurpijl omhoog laten bewegen

Maar twee punten met een lijn ertussen is niet helemaal wat we willen. Eigenlijk willen we dat de punt beweegt! Laten we de punt eerst stap voor stap omhoog verplaatsen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import turtle

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

vuurpijl = turtle.Turtle()

for i in range(10):
    vuurpijl.clear()
    vuurpijl.setposition(0, 15 * i)
    vuurpijl.dot(5)

Zie je dat de punt naar boven is verplaatst?

Opdrachten

  1. Wat gebeurt er als je de horizontale positie verandert? Dus als je de 0 in vuurpijl.setposition(0, 15 * i) verandert in bijvoorbeeld 40 of -40?
  2. En als je 15 in vuurpijl.setposition(0, 15 * i) groter of kleiner of juist negatief maakt?

5. En nu de vuurpijl echt zien bewegen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

vuurpijl = turtle.Turtle()
vuurpijl.hideturtle()

for i in range(100):
    vuurpijl.clear()
    vuurpijl.setposition(0, 3*i)
    vuurpijl.dot(5)
    venster.update()
    sleep(0.1)

Je kunt de pijl nu echt zien bewegen, doordat

Opdrachten

  1. Wat gebeurt er als je het aantal stappen verandert door 100 in range(100) vervangt door 50 of juist 150?
  2. Of wanneer je het getal in sleep(0.1) verkleint naar 0.02 of juist vergroot naar 0.2?
  3. Of wanneer je het getal 3 in vuurpijl.setposition(0, 3*i) verandert naar 2 of 5?

6. Een pijl beweegt meestal niet recht naar boven

We hebben in stap 4 gezien dat het aanpassen van de 0 in vuurpijl.setposition(0, 3*i) de horizontale positie van de pijl verandert. Maar een pijl beweegt meestal niet recht naar boven, maar eerder wat schuin:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

vuurpijl = turtle.Turtle()
vuurpijl.hideturtle()

for i in range(100):
    vuurpijl.clear()
    vuurpijl.setposition(i, 5*i)
    vuurpijl.dot(5)
    venster.update()
    sleep(0.1)

Je ziet nu dat de pijl zich naar rechtsboven verplaatst. Dit komt doordat we 0 met i hebben vervangen in vuurpijl.setposition(0, 5*i).

Opdrachten

  1. Wat gebeurt er nu als je -i gebruikt?
  2. Of -2 * i?

7. Meer vuurpijlen

Om zometeen makkelijker meerdere vuurpijlen af te kunnen steken, gaan we nu de code anders indelen. We gaan objecten en classes gebruiken:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

class Vuurpijl:
    def __init__(self):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.plaats_horizontaal = 0
        self.plaats_verticaal = 0
        self.snelheid_horizontaal = 1
        self.snelheid_verticaal = 3
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijl = Vuurpijl()
for i in range(100):
    vuurpijl.beweeg()
    venster.update()
    sleep(0.02)

Als je dit hebt uitgevoerd, zie je dat het nog steeds hetzelfde doet als bij stap 7. Dus wat is er nu eigenlijk veranderd en waarom?

Opdrachten

  1. Speel eens met de waarden van self.plaats_horizontaal, self.plaats_verticaal, self.snelheid_horizontaal, self.snelheid_verticaal?
  2. Kun je de pijl ook van rechtsboven in het venster naar linksonder laten bewegen? Wat moet daarvoor veranderen?

8. Fijn die voorbereiding, maar nu wil ik meerdere pijlen!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

class Vuurpijl:
    def __init__(self):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.plaats_horizontaal = 0
        self.plaats_verticaal = 0
        self.snelheid_horizontaal = 1
        self.snelheid_verticaal = 3
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijl1 = Vuurpijl()
vuurpijl2 = Vuurpijl()
for i in range(100):
    vuurpijl1.beweeg()
    vuurpijl2.beweeg()
    venster.update()
    sleep(0.02)

Zie je vuurpijl1 en vuurpijl2? Dat is alles wat er nodig is om twee vuurpijlen te maken. Superhandig!

Maar zíe je ze ook?? Hoe zou het komen dat je er maar één ziet?

9. Nu echt meerdere pijlen!

Doordat bij stap 8 de twee pijlen beiden op dezelfde plaats beginnen en precies dezelfde kant op gaan met dezelfde snelheid, kun je niet zien dat het er echt 2 zijn.

Om dat op te lossen, kunnen we de code aanpassen zodat we iedere pijl een eigen horizontale en verticale snelheid kunnen geven:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)

class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.plaats_horizontaal = 0
        self.plaats_verticaal = 0
        self.snelheid_horizontaal = snelheid_horizontaal
        self.snelheid_verticaal = snelheid_verticaal
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijl1 = Vuurpijl(-1, 3)
vuurpijl2 = Vuurpijl(0, 3)
vuurpijl3 = Vuurpijl(1, 3)
for i in range(100):
    vuurpijl1.beweeg()
    vuurpijl2.beweeg()
    vuurpijl3.beweeg()
    venster.update()
    sleep(0.02)

3 vuurpijlen

Wat is er veranderd?

Opdrachten

Speel eens met de waarden voor de vuurpijlen en kijk wat er gebeurt.

Wat gebeurt er als je dit gebruikt? (Vergeet niet vuurpijl4 ook te laten bewegen.)

1
2
3
4
vuurpijl1 = Vuurpijl(1, 3)
vuurpijl2 = Vuurpijl(-1, 3)
vuurpijl3 = Vuurpijl(1, -3)
vuurpijl4 = Vuurpijl(-1, -3)

10. Dit lijkt helemaal niet op vuurwerk!

Klopt! We hebben wat voorbereidend werk moeten doen en nu gaan we eens kijken of we het meer op vuurwerk kunnen laten lijken.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import turtle
from time import sleep

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)
venster.bgcolor("black")

class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color("gold")
        self.plaats_horizontaal = 0
        self.plaats_verticaal = -390
        self.snelheid_horizontaal = snelheid_horizontaal
        self.snelheid_verticaal = snelheid_verticaal
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijl1 = Vuurpijl(1, 3)
vuurpijl2 = Vuurpijl(-1, 3)
vuurpijl3 = Vuurpijl(0, 3)
vuurpijl4 = Vuurpijl(0.5, 3)
for i in range(200):
    vuurpijl1.beweeg()
    vuurpijl2.beweeg()
    vuurpijl3.beweeg()
    vuurpijl4.beweeg()
    venster.update()
    sleep(0.02)

Kijk:

4 vuurpijlen op een zwarte achtergrond

Wat is er veranderd?

1
2
3
4
5
6
7
venster.bgcolor("black")

class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.turtle.color("gold")
        self.plaats_horizontaal = 0
        self.plaats_verticaal = -390

De achtergrondkleur is zwart gemaakt door venster.bgcolor("black") toe te voegen.
De pijlen zijn goudgeel geworden door self.turtle.color("gold") toe te voegen.

Opdrachten

  1. Kijk eens op deze pagina en kies een andere kleur voor de achtergrond of de pijlen.

11. Meer pijlen! Ik wil meer pijlen!

Met al het werk dat we hebben gedaan, kunnen we nu makkelijk nog meer pijlen toevoegen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import turtle
from time import sleep
from random import randint

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)
venster.bgcolor("black")

class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color("gold")
        self.plaats_horizontaal = 0
        self.plaats_verticaal = -390
        self.snelheid_horizontaal = snelheid_horizontaal
        self.snelheid_verticaal = snelheid_verticaal
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijlen = []
for _ in range(10):
    vuurpijlen.append(Vuurpijl(randint(-15, 15)/10, randint(20, 30)/10))

for i in range(200):
    for vuurpijl in vuurpijlen:
        vuurpijl.beweeg()
    venster.update()
    sleep(0.02)

10 vuurpijlen in verschillende richtingen

Hier zitten de belangrijke wijzigingen:

1
2
3
4
5
6
7
vuurpijlen = []
for _ in range(10):
    vuurpijlen.append(Vuurpijl(randint(-15, 15)/10, randint(20, 30)/10))

for i in range(200):
    for vuurpijl in vuurpijlen:
        vuurpijl.beweeg()

Opdrachten

  1. Kijk eens of je nog meer pijlen kunt maken. Wat gebeurt er als je er heel veel hebt?
  2. Kun je de pijlen links/rechts uit het beeld laten vliegen?

12. Maar vuurpijlen vallen toch weer naar beneden?

Dat klopt. De zwaartekracht zorgt ervoor dat de vuurpijlen afremmen, tot stilstand komen en dan weer naar beneden vallen:

vuurpijlen met zwaartekracht

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import turtle
from time import sleep
from random import randint

venster = turtle.Screen()
venster.setup(800, 800)
venster.tracer(0)
venster.bgcolor("black")

class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color("gold")
        self.plaats_horizontaal = 0
        self.plaats_verticaal = -390
        self.snelheid_horizontaal = snelheid_horizontaal
        self.snelheid_verticaal = snelheid_verticaal
        self.zwaartekracht = 0.06
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.snelheid_verticaal = self.snelheid_verticaal - self.zwaartekracht
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)

vuurpijlen = []
for _ in range(10):
    vuurpijlen.append(Vuurpijl(randint(-15, 15)/10, 6 + randint(20, 30)/10))

for i in range(300):
    for vuurpijl in vuurpijlen:
        vuurpijl.beweeg()
    venster.update()
    sleep(0.02)

Dit zijn de belangrijkste wijzigingen:

1
2
3
4
5
6
class Vuurpijl:
    def __init__(self, snelheid_horizontaal, snelheid_verticaal):
        self.zwaartekracht = 0.06
        
    def beweeg(self):
        self.snelheid_verticaal = self.snelheid_verticaal - self.zwaartekracht

Hier zie je een variabele met de zwaartekracht met waarde 0.06. Die waarde wordt elke keer dat we het vuurwerk tekenen van de verticale snelheid afgetrokken. Daardoor gaat de vuurpijl steeds langzamer omhoog om uiteindelijk weer naar beneden te vallen.

Opdrachten

  1. Wat gebeurt er als je de zwaartekracht vergroot? Bijvoorbeeld naar waarde 0.1?
  2. Of verkleint naar bijvoorbeeld waarde 0.04?

13. Doe maar verschillende pijlen

De pijlen gaan al verschillende richtingen op en hebben verschillende snelheden, maar verschillende kleuren zou ook leuk zijn!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import turtle
from time import sleep
from random import randint

venster = turtle.Screen()
venster.setup(800, 800)
venster.colormode(255)
venster.tracer(0)
venster.bgcolor("black")

class Vuurpijl:
    def __init__(self, kleur, snelheid_horizontaal, snelheid_verticaal):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color(*kleur)
        self.plaats_horizontaal = 0
        self.plaats_verticaal = -390
        self.snelheid_horizontaal = snelheid_horizontaal
        self.snelheid_verticaal = snelheid_verticaal
        self.zwaartekracht = 0.06
        
    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.snelheid_verticaal = self.snelheid_verticaal - self.zwaartekracht
        self.turtle.clear()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.dot(5)
    
def zomaar_een_kleur():
    return randint(0, 255), randint(0, 255), randint(0, 255)

vuurpijlen = []
for _ in range(10):
    vuurpijlen.append(Vuurpijl(zomaar_een_kleur(), randint(-15, 15)/10, 6 + randint(20, 30)/10))

for i in range(400):
    for vuurpijl in vuurpijlen:
        vuurpijl.beweeg()
    venster.update()
    sleep(0.02)

R G B

Beeldschermen kunnen eigenlijk maar drie kleuren maken: rood, groen en blauw. Door die kleuren te mengen kun je alle andere kleuren maken.

In deze tabel zie je links de hoeveelheden van iedere kleur en rechts welke kleur het mengsel oplevert. Voor iedere kleur kun je een waarde van 0 tot en met 255 gebruiken:

RGBde mengkleur
000
25500
2552550
02550
0255255
00255
2550255
255128255
128128128
255255255

Als je geen van de kleuren gebruikt, krijg je zwart!
Gebruik je ze allemaal maximaal, dan krijg je wit!
Samen kun je daarmee ruim 16 miljoen verschillende kleuren maken!

Wat is er veranderd in de code?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Vuurpijl:
    def __init__(self, kleur, snelheid_horizontaal, snelheid_verticaal):
        self.turtle.color(*kleur)

    
def zomaar_een_kleur():
    return randint(0, 255), randint(0, 255), randint(0, 255)

for _ in range(10):
    vuurpijlen.append(Vuurpijl(zomaar_een_kleur(), randint(-15, 15)/10, 6 + randint(20, 30)/10))

Opdracht

Voer het programma meerdere keren uit. Klopt het dat de kleuren iedere keer anders zijn?

14. Deze pijlen ploffen niet uit elkaar… ☹️

Of toch wel, maar dan moet je nog wel heel wat aan de code veranderen…

Kopiëer en plak deze code maar in Thonny en je zult het zien!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import turtle
from time import sleep
from random import randint
from math import sin, cos, pi

aantal_vuurpijlen = 10
stukken = 11
start_positie = (0, -390)

class Vuurpijl:
    def __init__(self, kleur, plaats, snelheid):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color(*kleur)
        self.color = kleur
        self.plaats_horizontaal = plaats[0]
        self.plaats_verticaal = plaats[1]
        self.snelheid_horizontaal = snelheid[0]
        self.snelheid_verticaal = snelheid[1]
        self.vanaf_de_grond = plaats == start_positie
        self.zwaartekracht = 0.06

    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.snelheid_verticaal = self.snelheid_verticaal - self.zwaartekracht
        self.turtle.clear()
        self.turtle.penup()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.pendown()
        self.turtle.dot(5)

    def is_boven(self):
        return self.snelheid_verticaal < 0

    def positie(self):
        return self.plaats_horizontaal, self.plaats_verticaal

    def snelheid(self):
        return self.snelheid_horizontaal, self.snelheid_verticaal

    def clear(self):
        self.turtle.clear()

    def is_vanaf_de_grond(self):
        return self.vanaf_de_grond
    
    def kleur(self):
        return self.color

def zomaar_een_kleur():
    return randint(1, 255), randint(1, 255), randint(1, 255)


def zomaar_een_richting_en_snelheid(snelheid, i):
    hoek = i * 180 / stukken
    return (snelheid[0] + 1 * sin(pi * hoek),
            snelheid[1] + 1 * cos(pi * hoek))


def main():
    venster = turtle.Screen()
    venster.setup(800, 800)
    venster.colormode(255)
    venster.tracer(0)
    venster.bgcolor("black")

    vuurpijlen = []
    while True:
        for vuurpijl in vuurpijlen:
            vuurpijl.beweeg()
            if vuurpijl.is_vanaf_de_grond() and vuurpijl.is_boven():
                vuurpijl.clear()
                for j in range(stukken):
                    vuurpijlen.append(Vuurpijl(vuurpijl.kleur(), vuurpijl.positie(),
                                               zomaar_een_richting_en_snelheid(vuurpijl.snelheid(), j)))
                vuurpijlen.remove(vuurpijl)
            if vuurpijl.positie()[1] < -400:
                vuurpijlen.remove(vuurpijl)
        if len(vuurpijlen) < aantal_vuurpijlen:
            vuurpijlen.append(Vuurpijl(zomaar_een_kleur(), start_positie, (randint(-15, 15) / 10, 6 + randint(20, 30) / 10)))
        venster.update()
        sleep(0.02)

if __name__ == "__main__":
    main()

Iets te veel wijzigingen om uit te leggen, maar…

15. Waar blijft de nieuwjaarswens?

Gaan we meteen aan werken:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import turtle
from time import sleep
from random import randint
from math import sin, cos, pi

aantal_vuurpijlen = 10
stukken = 11
start_positie = (0, -390)

class Vuurpijl:
    def __init__(self, kleur, plaats, snelheid):
        self.turtle = turtle.Turtle()
        self.turtle.hideturtle()
        self.turtle.color(*kleur)
        self.color = kleur
        self.plaats_horizontaal = plaats[0]
        self.plaats_verticaal = plaats[1]
        self.snelheid_horizontaal = snelheid[0]
        self.snelheid_verticaal = snelheid[1]
        self.vanaf_de_grond = plaats == start_positie
        self.zwaartekracht = 0.06

    def beweeg(self):
        self.plaats_verticaal = self.plaats_verticaal + self.snelheid_verticaal
        self.plaats_horizontaal = self.plaats_horizontaal + self.snelheid_horizontaal
        self.snelheid_verticaal = self.snelheid_verticaal - self.zwaartekracht
        self.turtle.clear()
        self.turtle.penup()
        self.turtle.setposition(self.plaats_horizontaal, self.plaats_verticaal)
        self.turtle.pendown()
        self.turtle.dot(5)

    def is_boven(self):
        return self.snelheid_verticaal < 0

    def positie(self):
        return self.plaats_horizontaal, self.plaats_verticaal

    def snelheid(self):
        return self.snelheid_horizontaal, self.snelheid_verticaal

    def clear(self):
        self.turtle.clear()

    def is_vanaf_de_grond(self):
        return self.vanaf_de_grond
    
    def kleur(self):
        return self.color

def zomaar_een_kleur():
    return randint(1, 255), randint(1, 255), randint(1, 255)


def zomaar_een_richting_en_snelheid(snelheid, i):
    hoek = i * 180 / stukken
    return (snelheid[0] + 1 * sin(pi * hoek),
            snelheid[1] + 1 * cos(pi * hoek))


def main():
    venster = turtle.Screen()
    venster.setup(800, 800)
    venster.colormode(255)
    venster.tracer(0)
    venster.bgcolor("black")

    text = turtle.Turtle()
    text.hideturtle()
    text.color("gold")
    text.penup()
    text.setposition((0, -200))
    text.pendown()
    text.write("Gelukkig 2025!", font=("serif", 70, "normal"), align="center")

    vuurpijlen = []
    while True:
        for vuurpijl in vuurpijlen:
            vuurpijl.beweeg()
            if vuurpijl.is_vanaf_de_grond() and vuurpijl.is_boven():
                vuurpijl.clear()
                for j in range(stukken):
                    vuurpijlen.append(Vuurpijl(vuurpijl.kleur(), vuurpijl.positie(),
                                               zomaar_een_richting_en_snelheid(vuurpijl.snelheid(), j)))
                vuurpijlen.remove(vuurpijl)
            if vuurpijl.positie()[1] < -400:
                vuurpijlen.remove(vuurpijl)
        if len(vuurpijlen) < aantal_vuurpijlen:
            vuurpijlen.append(Vuurpijl(zomaar_een_kleur(), start_positie, (randint(-15, 15) / 10, 6 + randint(20, 30) / 10)))
        venster.update()
        sleep(0.02)

if __name__ == "__main__":
    main()

Wat is er veranderd?

1
2
3
4
5
6
7
    text = turtle.Turtle()
    text.hideturtle()
    text.color("gold")
    text.penup()
    text.setposition((0, -200))
    text.pendown()
    text.write("Gelukkig 2025!", font=("serif", 70, "bold"), align="center")

Opdrachten

Met alles wat je in de voorgaande stappen hebt geleerd, kun je het volgende proberen.

  1. Verander de kleur van de tekst in rood of een andere kleur.
  2. Kun je de tekst boven in het venster plaatsen?
  3. Verander de tekst naar je eigen nieuwjaarswens. Als de tekst te groot wordt, kun je de letters kleiner maken door getal 70 op regel 7 te verlagen.

Het eindresultaat

We hebben vandaag veel gedaan en hopelijk heb je veel geleerd!

CoderDojo wenst je een… Gelukkig 2025!

Licentie

Deze instructies worden, net als alle andere instructies van CoderDojo Nijmegen, aangeboden onder een Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Licentie.

Creative Commons License