Een skispel in Python

Materialen: Onderwerpen:

In deze opdracht gaan wij een skispel in Python maken. In dit spel zoeft Rob de robot de piste af. Om mee te kunnen doen voor de volgende Robolyimpische Spelen, moet Rob zoveel mogelijk punten halen. Rob krijgt punten door tussen de vlaggen te skiën, wat nog niet zo makkelijk is.

Wil je deze pagina offline gebruiken?
Bijvoorbeeld om hem makkelijk naast je computer te houden? Dat kan!

(Denk wel aan de bomen voordat je deze pagina print!)

Voorbereiding

Om deze opdracht te doen heb je dit nodig:

Installeer PyGame Zero

In de Python-opdracht ‘Raad het getal!’ werkten wij met de shell. Daarin kunnen wij tekst schrijven, maar geen plaatjes of animaties laten zien.

Om toch een visueel spel met animaties te maken moeten wij eerst een Python module installeren. Een Python module bestaat uit code die al door iemand anders geschreven is. Die code kunnen wij zo handig opnieuw gebruiken!

Voor deze opdracht gebruiken wij de module PyGame Zero.

Volg deze stappen om PyGame Zero te installeren:

  1. Open de Windows command line

    In de Windows Command Line kan je makkelijk commando’s laten uitvoeren door je computer. Zo kan je programma’s opstarten, maar ook bestanden maken en installeren.
    Wij gaan de Command Line gebruiken om een Python module te installeren met het programma pip, dat speciaal hiervoor bedoeld is.

    Druk tegelijkertijd op de Windows-toets en de r-toets op je toetsenbord. (de Windows-toets zit tussen de Ctrl en de Alt-toets in)
    Je zou het volgende venster moeten zien:

    Typ in het tekstvak naast ‘Openen:’ de tekst cmd in, en druk op de Enter-toets.
    Dit opent de Command Line, een zwart venster met witte tekst.

  2. Installeer PyGame Zero met Pip.

    Typ deze tekst in de Command Line:
    pip install pgzero
    Druk daarna op de Enter-toets.

    PyGame Zero wordt nu geïnstalleerd! Als de installatie gelukt is, zou je dit bericht moeten zien, onderaan in de Command Line:
    Succesfully installed pgzero-1.2

Een eerste opzet.

PyGame Zero werkt alleen wanneer je Python programma een bepaalde vorm heeft. Om je op weg te helpen, hebben wij daarom een startprogramma voor je gemaakt. Het startprogramma kan je in het startbestand vinden. Het heeft de naam game.py.

Wanneer je in het startprogramma kijkt, zie je deze code:

# Laad Pygame Zero.
import pgzrun

# Hiermee kan je willekeurige getal maken, bijvoorbeeld met randrange.
import random

# Breedte en hoogte van het speelveld.
WIDTH  = 400
HEIGHT = 800

# Maak Rob, de skiënde robot, en zet hem op de juiste plek.
# Rob is een zogenaamde acteur, iets in het spel dat kan bewegen.
rob     = Actor('robot_links')
rob.pos = 200, 200

# Maak de slalom vlaggen, zet ze willekeurig aan de bodem van het speelveld.
slalom = Actor('slalom_baan')
slalom.x = randrange(0, WIDTH)
slalom.y = HEIGHT

# De snelheid waarmee Rob naar links of rechts beweegt, deze komt later nog van pas.
rob.vx  = 0.0

# De punten die Rob heeft verdient. Wij zetten hem hier op 0 aan het start van het spel.
rob.punten = 0

# Deze functie tekent het speelscherm.
# Deze functie wordt heeeel vaak aangeroepen door PyGame Zero,
# zodat het net lijkt alsof de acteurs (Rob en de slalom vlaggen) vloeiend bewegen!
def draw():
    pass

# Deze functie veranderd de acteurs in het spel als dat nodig is,
# bijvoorbeeld wanneer je een toets op je toetsenbord drukt.
def update(dt):    
    pass

# Start het spel!
pgzrun.go()

De regels code die met een hashtag (#) beginnen is commentaar. Commentaar doet niks maar kan je gebruiken om je code uit te leggen. Zo kunnen andere mensen die je code lezen de code beter begrijpen. Het helpt je ook om later je eigen code te kunnen begrijpen, wanneer je al een lange tijd niet meer naar je code hebt gekeken en niet meer precies weet wat het doet.

Als jij het commentaar leest, krijg jij dan al een idee hoe de code werkt?

Voer het programma eens uit. Klik hiervoor in het menu van IDLE op Run en daarna op Run Module.

Je ziet nu niks interessants…. Alleen een zwart venster. Laten wij hierin verandering brengen!

Tip: Weet je even niet verder? Via deze link vind je de code van het uiteindelijke spel.

Het speelscherm laten tekenen

Ergens in het startprogramma zie je deze code staan:

def draw():
    pass

Dit is een functie definitie. Functies, zoals print, zijn wij al tegengekomen in de vorige opdracht. Met een functie definitie kan je zelf een functie maken en bepalen wat het doet!

Functie definities herken je aan de afkorting def dat voor de naam van de functie staat. def staat voor definition, dit is Engels voor definitie.

PyGame Zero roept de draw functie aan om het speelscherm te tekenen. In ons geval staat er nog niks in de definitie van de draw functie… Behalve dan het commando pass, wat ‘doe hier helemaal niks’ betekent in de Python taal.

De sneeuw laten tekenen

Laten wij eerst zeggen dat het scherm een witte achtergrond moet krijgen. Rob moet natuurlijk sneeuw hebben om op te skiën! Vervang daarvoor de draw functie definitie met deze code:

def draw():
    screen.fill('white')

Let op: zorg ervoor dat je vier spaties voor screen.fill hebt staan. Anders snapt Python niet dat deze regel code bij de functie definitie van draw hoort.

Als je nu het programma uitvoert zie je een witte achtergrond.

De slalom vlaggen laten tekenen.

Rob moet tussen de slalom vlaggen skieën om punten te halen.

Om de slalom vlaggen te laten tekenen voeg je deze code aan de draw functie toe:

slalom.draw()

De draw functie ziet er dan zo uit:

def draw():
    screen.fill('white')
    slalom.draw()

De punten van Rob laten tekenen.

Om te laten zien hoeveel punten Rob heeft verdient tekenen wij wat tekst op het speelveld.
Voeg daarvoor deze regels code toe aan de draw functie:

score_text = 'Score: ' + str(rob.punten)
screen.draw.text(score_text, (20,20), color='black')

Deze code vertelt Python dat het de tekst 'Score: ', plus de punten die Rob heeft verdient moet tonen. De (20, 20) vertelt Python de plek op het speelveld waar de score moet staan (linksboven) en color='black' geeft de kleur van de tekst aan.

Rob de skiër laten tekenen

Om Rob te tekenen voeg je deze code aan de draw functie toe:

rob.draw()

Voeg deze regel toe na het tekenen van de slalom vlaggen, maar voor het tekenen van de score. De draw functie ziet er dan zo uit:

def draw():
    screen.fill('white')
    slalom.draw()
    rob.draw()
    score_tekst = 'Score: ' + str(rob.punten)
    screen.draw.text(score_tekst, (20,20), color='black')

Als je het programma nu uitvoert, zie je Rob de robot verschijnen. Hij staat aan de bovenkant van het venster.

Maar ja, veel beweging zit er nog niet in Rob. Zo wint hij de Robolympische Spelen nooit…
In het volgende deel zorgen wij ervoor dat Rob over de piste zoeft!

Rob en de slalom vlaggen laten bewegen

In het programma zie je nog een andere functie definitie staan. Deze heeft de naam update:

def update():
    pass

Net als bij de draw functie doet de update functie nog helemaal niks.

Rob over de piste laten bewegen

Laten wij een eigen functie maken die Rob over de piste laat bewegen.

Voeg daarvoor deze regels code aan je programma toe.

# Deze functie laar Rob naar links en rechts bewegen.
def beweeg_rob():
    # Dit zorgt voor wat wrijving op de piste.
    rob.vx = rob.vx * 0.98

    # Update de positie van Rob op basis van zijn snelheid.
    rob.x = rob.x + rob.vx

    # Verhoog de snelheid naar links wanneer de speler op de linker pijltjestoets drukt.
    if keyboard.left:
        rob.vx -= 0.2
        rob.image = 'robot_links'

    # Verhoog de snelheid naar rechts wanneer de speler op de rechter pijltjestoets drukt.
    if keyboard.right:
        rob.vx += 0.2
        rob.image = 'robot_rechts'

Nu moeten wij er alleen nog voor zorgen dat de beweeg_rob functie wordt aangeroepen in de update functie. Vervang hiervoor de update functie met deze regels code:

def update():
    # Roep de beweeg_rob functie aan.
    beweeg_rob()

Als je het programma nu uitvoert kan je Rob naar links en rechts laten bewegen. Druk maar eens op de linker of rechter pijltjestoets nadat het programma is gestart.

De slalom vlaggen laten bewegen

Er mist nog iets… Rob kan alleen punten halen wanneer hij tussen de slalom vlaggen door skiet. Maar de vlaggen bewegen nog niet. Laten wij de vlaggen laten bewegen!

Wij gaan hiervoor een eigen functie definitie toevoegen. Net als voor het bewegen van Rob.

Voeg deze code toe aan het einde van het programma. Lees het commentaar in de code om te zien wat de regels doen!

# Deze functie laat de slalom vlaggen naar boven bewegen.
def beweeg_slalom_vlaggen():
    # Beweeg de vlaggen een stukje naar boven.
    slalom.y -= SPEED
    # Als de vlaggen boven zijn aangekomen...
    if slalom.y < 0:
        # .. zet ze weer beneden het speelveld, ...
        slalom.y = HEIGHT
        # .. op een willekeurige plek, zodat Rob moet bewegen om tussen de vlaggen door te skiën!
        slalom.x = randrange(0, WIDTH)

Nu moeten wij de beweeg_slalom_vlaggen functie nog aanroepen wanneer het spel geüpdate wordt:

def update():
    beweeg_rob()
    beweeg_slalom_vlaggen()

Als je het programma nu uitvoert zie je de slalom vlaggen van beneden naar boven bewegen! Kan jij Rob tussen de vlaggen door bewegen?

Er ontbreekt nog één onderdeel om het spel af te maken: de puntentelling. Elke keer wanneer Rob tussen de vlaggen door zoeft moet hij een punt krijgen.

De puntentelling

Als je goed kijkt zie je aan de bovenkant van het programma deze regel staan:

rob.punten = 0

Hiermee zetten wij de punten die Rob heeft verdient aan de start van het skispel op 0.

Laten wij een functie toevoegen die kijkt of Rob tussen de vlaggen skiet. Als Rob dit doet, krijgt hij er een punt bij. Voeg hiervoor deze regels code toe:

# Deze functie kijkt of Rob tussen de slalom-vlaggen heen skiet.
# Zo ja, dan wordt de score met 1 punt verhoogd.
def update_score():
    if rob.y == slalom.y:
        if rob.x > slalom.x - 50 and rob.x < slalom.x + 50:
            rob.punten += 1

Weet jij al hoe de code hierboven werkt?

Het skispel in Python is af!

Gefeliciteerd! Je hebt nu een skispel in Python geschreven :).

Voer het programma maar uit, dan kun je het spel spelen. Kan jij Rob zoveel mogelijk punten laten verdienen?