Informatik

Tastatur und Maus

Bisher liefen deine Programme von oben nach unten durch – und dann war Schluss. Was gezeichnet wird, stand vorher fest.

Jetzt drehen wir das um: Das Programm wartet, und du entscheidest mit Tastatur und Maus, was passiert. Dafür brauchst du genau das, was du in diesem Kapitel gelernt hast: eigene Funktionen.

Aufgabe 1: Die Turtle fernsteuern

a) Starte das Programm. Klicke einmal auf die Zeichenfläche und drücke dann die Pfeiltasten.

b) Analysiere das Programm und erläutere, was onkey und listen bewirken.

c) Beim Aufruf von onkey steht hinter vor keine Klammer. Probiere aus, was passiert, wenn du onkey(vor(), "Up") schreibst, und erkläre den Unterschied.

from turtle import * shape("turtle") def vor(): forward(10) def links(): left(30) def rechts(): right(30) onkey(vor, "Up") onkey(links, "Left") onkey(rechts, "Right") listen()
Tipp: Wann laufen die Funktionen?

Lies das Programm von oben nach unten: Es definiert drei Funktionen, ruft aber keine davon selbst auf. Am Ende ist das Programm fertig – und trotzdem bewegt sich die Turtle, sobald du eine Taste drückst.

Wer ruft die Funktionen also auf?

onkey(vor, "Up")
listen()
  • onkey(funktion, taste) merkt sich: Wenn diese Taste gedrückt wird, rufe diese Funktion auf.
  • listen() sorgt dafür, dass die Zeichenfläche auf die Tastatur hört.
  • Die Funktion wird ohne Klammern übergeben. Mit Klammern würde sie sofort einmal aufgerufen – übergeben würde dann nur ihr Ergebnis, und das ist None.
  • Ein Tastendruck ist ein Ereignis (englisch event). Ein Programm, das auf Ereignisse wartet und reagiert, heißt ereignisgesteuert.
  • Die Zeichenfläche hört erst zu, wenn du sie einmal angeklickt hast.
Taste Name
Pfeiltasten "Up", "Down", "Left", "Right"
Leertaste "space"
Buchstaben und Ziffern "a", "b", …, "1", "2", …

Aufgabe 2: Die Zeichenmaschine

Erweitere das Programm aus Aufgabe 1 zu einer Zeichenmaschine:

  • Mit der Pfeiltaste nach unten fährt die Turtle 10 Schritte zurück.
  • Die Tasten 1, 2 und 3 wechseln die Stiftfarbe zu Rot, Grün und Blau.
  • Die Taste c löscht die Zeichnung.
  • Die Leertaste hebt den Stift an, wenn er unten ist, und senkt ihn, wenn er oben ist.

Zeichne damit ein Bild, das du jemandem zeigen willst.

from turtle import * shape("turtle") def vor(): forward(10) def links(): left(30) def rechts(): right(30) onkey(vor, "Up") onkey(links, "Left") onkey(rechts, "Right") listen()
Tipp 1: Für jede Taste eine Funktion

Jede Taste braucht ihre eigene kleine Funktion, zum Beispiel:

def rot():
    pencolor("red")
 
 
onkey(rot, "1")

Achte darauf, dass alle onkey-Zeilen nach den Funktionen stehen.

Tipp 2: Ist der Stift unten?

isdown() liefert True, wenn der Stift unten ist, und sonst False – genau wie xcor() einen Wert zurückliefert. Damit kannst du entscheiden:

def stift():
    if isdown():
        penup()
    else:
        pendown()
Lösung. Erfrage das Passwort bei deiner Lehrkraft.

Aufgabe 3: Mausklicks

Auch auf die Maus kann ein Programm reagieren. Dabei will es aber nicht nur wissen, dass geklickt wurde, sondern auch wo.

a) Starte das Programm und klicke an verschiedene Stellen der Zeichenfläche.

b) Die Funktion klick hat zwei Parameter, wird aber nirgends von dir aufgerufen. Erkläre, woher x und y ihre Werte bekommen.

from turtle import * shape("turtle") def klick(x, y): goto(x, y) onscreenclick(klick)

onscreenclick(funktion) ruft die Funktion bei jedem Klick auf die Zeichenfläche auf. Die Funktion muss zwei Parameter haben: Für sie setzt der Computer die Koordinaten der Klickstelle als Argumente ein.

c) Verändere das Programm zu einem Nachthimmel: Jeder Klick setzt an der Klickstelle einen Punkt mit zufälliger Größe zwischen 5 und 25. Liegt die Klickstelle in der oberen Hälfte, ist der Punkt gelb (ein Stern), sonst grün (ein Busch). Es sollen keine Linien entstehen.

from turtle import * from random import randint bgcolor("midnightblue") hideturtle() speed(0) penup() def klick(x, y): goto(x, y) onscreenclick(klick)
Tipp: Welche Hälfte?

Das kennst du aus Funktionen mit Rückgabewert: Der Ursprung liegt in der Mitte. Hier musst du nicht einmal ycor() fragen – der Parameter y verrät dir die Höhe der Klickstelle schon.

Lösung. Erfrage das Passwort bei deiner Lehrkraft.

Aufgabe 4: Die Turtle läuft von allein

Für ein Spiel muss die Turtle sich auch bewegen, wenn gerade niemand eine Taste drückt.

a) Starte das Programm, klicke auf die Zeichenfläche und steuere die Turtle mit den Pfeiltasten nach links und rechts.

b) Erläutere, warum die Turtle immer weiterläuft, obwohl im Programm keine Schleife vorkommt.

c) Im Moment läuft die Turtle aus dem Bild heraus. Verändere schritt so, dass sie stehen bleibt, sobald sie den Rand des Quadrats erreicht.

from turtle import * shape("turtle") speed(0) # Rand zeichnen penup() goto(-200, -200) pendown() for i in range(4): forward(400) left(90) penup() goto(0, 0) pendown() def links(): left(90) def rechts(): right(90) def schritt(): forward(5) ontimer(schritt, 50) onkey(links, "Left") onkey(rechts, "Right") listen() schritt()

ontimer(funktion, millisekunden) ruft die Funktion einmal auf, nachdem die angegebene Zeit vergangen ist.

Ruft sich die Funktion am Ende selbst wieder mit ontimer auf, entsteht eine Wiederholung ohne Schleife – eine Spielschleife. Zwischen zwei Schritten bleibt Zeit, auf Tasten und Klicks zu reagieren.

Soll die Wiederholung aufhören, ruft die Funktion ontimer einfach nicht mehr auf.

Tipp 1: Wann ist die Turtle am Rand?

Das Quadrat reicht von -200 bis 200 – in x-Richtung und in y-Richtung. Am Rand ist die Turtle, wenn xcor() größer als 200 oder kleiner als -200 ist. Dasselbe gilt für ycor().

Tipp 2: Wie bleibt sie stehen?

Die Turtle läuft nur weiter, solange schritt sich selbst wieder per ontimer aufruft. Steck den Aufruf von ontimer in eine Verzweigung:

def schritt():
    forward(5)
    if ...:
        write("Stopp!")
    else:
        ontimer(schritt, 50)
Lösung. Erfrage das Passwort bei deiner Lehrkraft.

Aufgabe 5: Das Spiel „Hungrige Turtle"

Jetzt hast du alle Bausteine für ein kleines Spiel: Die Turtle läuft von allein, du lenkst sie mit den Pfeiltasten zum Futter. Berührt sie den Rand, ist das Spiel verloren.

Für das Futter benutzt das Programm eine zweite Turtle mit dem Namen futter. Befehle für sie schreibst du mit einem Punkt dahinter: futter.goto(...). Mehr dazu findest du in der Turtle-Dokumentation.

a) Spiele das Spiel. Gestartet wird es mit einem Klick auf die Zeichenfläche.

b) Analysiere das Programm. Finde heraus, welche Funktion bei welchem Ereignis aufgerufen wird.

c) Ändere das Spiel nach deinen Vorstellungen. Ideen findest du unter dem Programm.

from turtle import * from random import randint shape("turtle") speed(0) # Spielfeld zeichnen penup() goto(-200, -200) pendown() for i in range(4): forward(400) left(90) penup() goto(0, 0) color("green") pendown() # Das Futter ist eine zweite Turtle futter = Turtle() futter.shape("circle") futter.color("orange") futter.speed(0) futter.penup() futter.goto(randint(-180, 180), randint(-180, 180)) def links(): left(90) def rechts(): right(90) def am_rand(): return xcor() > 200 or xcor() < -200 or ycor() > 200 or ycor() < -200 def ende(text): penup() goto(0, 0) write(text, align="center", font=("Arial", 24, "bold")) def schritt(): forward(5) if distance(futter) < 15: ende("Gewonnen!") elif am_rand(): ende("Verloren!") else: ontimer(schritt, 50) def start(x, y): onscreenclick(None) schritt() onkey(links, "Left") onkey(rechts, "Right") listen() onscreenclick(start)
  • distance(futter) liefert den Abstand zur Turtle futter. Ist er kleiner als 15, berühren sich die beiden.
  • am_rand() ist eine eigene Funktion mit Rückgabewert: Sie liefert True oder False und macht die Bedingung in schritt gut lesbar.
  • ende(text) schreibt die Meldung mittig ins Spielfeld – einmal definiert, für Sieg und Niederlage benutzt.
  • onscreenclick(None) meldet die Funktion wieder ab. So startet ein zweiter Klick nicht noch eine zweite Spielschleife.

Ideen zum Weiterentwickeln

Suche dir eine oder mehrere Ideen aus:

  • Schneller oder langsamer: Verändere die Wartezeit oder die Schrittweite.
  • Steuern mit vier Tasten: Mit setheading(90) schaut die Turtle nach oben, mit 0 nach rechts, mit 180 nach links, mit 270 nach unten.
  • Mehr Futter: Das Futter springt nach dem Fressen an eine neue Stelle, und das Spiel läuft weiter. Erst nach fünf Mal Fressen ist es gewonnen.
  • Eigene Idee: Hindernisse, die man nicht berühren darf, ein kleineres Spielfeld, eine zweite Person mit den Tasten w, a, s, d …
Tipp: Mitzählen mit global

Für „Mehr Futter" muss das Spiel mitzählen. Eine Variable, die außerhalb einer Funktion angelegt wurde, kann die Funktion zwar lesen, aber nicht verändern. Damit sie es darf, schreibst du global davor:

gefressen = 0
 
 
def schritt():
    global gefressen
    forward(5)
    if distance(futter) < 15:
        gefressen = gefressen + 1
        futter.goto(randint(-180, 180), randint(-180, 180))
    ...

:::protect{password="turtle-4-tasten-4" description="Lösung für „Mehr Futter". Erfrage das Passwort bei deiner Lehrkraft."}

Die Funktion schritt wird ersetzt, darüber kommt die Zählvariable:

gefressen = 0
 
 
def schritt():
    global gefressen
    forward(5)
    if distance(futter) < 15:
        gefressen = gefressen + 1
        futter.goto(randint(-180, 180), randint(-180, 180))
 
    if gefressen == 5:
        ende("Gewonnen!")
    elif am_rand():
        ende("Verloren!")
    else:
        ontimer(schritt, 50)

:::


Selbsttest

Tastatur und Maus

Teilbare URL erstellen

Abschnitte auswählen