361
Uhr
Muster 18: Erzeugen benutzerdefinierter Turtle-
Shapes
1. Schritt: Erzeugung der Punktliste für die Turtle-Form mit einer Turtle
t
:
t.begin_poly()
Grafik-Anweisungen
t.end_poly()
pl = t.get_poly()
2. Schritt: Registrierung der Shape unter einem Namen
screen.register_shape(namenstring, pl)
3. Schritt: Verwendung der Shape:
t.shape(namenstring)
Uhr
Mit den neu erworbenen Kenntnissen über
ontimer()
und das Herstellen eigener Turtle-Shapes wollen wir
nun ein Programm schreiben, das eine einfache Uhr
auf dem Bildschirm darstellt.
Das sieht durchaus einfach aus. Das Ganze besteht aus
einem Ziffernblatt und einem (Sekunden-)Zeiger.
(Überlegungen zu einer vollständigeren Uhr mit wei-
teren Zeigern folgen weiter hinten.) Der Sekundenzei-
ger muss sich drehen – wie es eine Turtle kann. Wir
werden ihn daher als »Turtle mit Zeigerform« imple-
mentieren.
Da dieses Kapitel bis hierher schon ein wenig anstren-
gend war, gönne ich dir eine kleine Erholungspause, in
der du eine Funktion für das Ziffernblatt erstellen kannst. Das ist für einen
alten Turtle-Grafik-Hasen wie dich inzwischen kein Problem mehr.
>
Öffne ein Editor-Fenster von der IPI-S
HELL
aus, schreibe einen Kopf-
kommentar für
uhr_arbeit.py
und speichere.
Start der Aufzeichnungen der Polygonpunkte
… zeichnen die neue Turtle-Shape
Ende der Aufzeichnungen der Punkte
Punktliste wird der Variabeln
pl
zugewiesen
362
Ereignisgesteuerte Programme
Kapitel
13
>
Schreibe nach den nötigen
import
-Anweisungen eine Funktion
zif-
fernblatt(radius)
und ein Hauptprogramm, das in ein quadrati-
sches Turtle-Grafik-Fenster das Ziffernblatt zeichnet.
Ich habe das auch getan. Um dir zu zeigen, dass man auch mit der altbe-
kannten anonymen Turtle eigene Shapes machen kann, habe ich die aus-
nahmsweise noch einmal verwendet. Außerdem funktioniert für sie nütz-
licherweise die Funktion
jump()
aus unserer Bibliothek.
Bei mir sieht der Code, wie immer eine von vielen möglichen Lösungen, wie
folgt aus:
from turtle import *
from mytools import jump
def ziffernblatt(radius):
reset()
pensize(7)
for i in range(12):
jump(radius)
fd(25)
jump(-radius-25)
rt(30)
def uhr():
screen.setup(400, 400)
ziffernblatt(160)
if __name__ == "__main__":
screen = Screen()
uhr()
Die Anweisung
screen = Screen()
erzeugt wieder den globalen Namen
screen
, den wir auch später noch für den Aufruf von
screen
-Methoden
benötigen werden.
Als Nächstes schreiben wir eine Funktion, die den Zeiger zeichnet: vom
Ursprungsort der Turtle ausgehend und nach oben zeigend. Weil wir aber
im Hinterkopf schon die Notwendigkeit notiert haben, später Zeiger ande-
rer Größe zu erzeugen (Minuten-, Sekundenzeiger), verpassen wir der Funk-
tion
zeiger()
zwei Parameter:
laenge
für die Länge des Schaftes und
spitze
für die Seitenlänge des Dreiecks, das die Zeigerspitze bildet.
363
Uhr
def zeiger(laenge, spitze):
fd(laenge)
rt(90)
fd(spitze/2)
lt(120)
fd(spitze)
lt(120)
fd(spitze)
lt(120)
fd(spitze/2)
>
Füge den Code dieser Funktion gleich hinter den
import
-Anweisun-
gen in das Programm
uhr_arbeit.py
ein. Führe das Programm aus
und teste im Direktmodus mit dem IPI, ob diese Funktion verschiede-
ne Zeiger korrekt zeichnen kann.
>>> zeiger(60,30)
>>> pu(); home(); pd()
>>> rt(120)
>>> zeiger(100, 15)
>>> pu(); home(); pd()
>>> rt(270)
>>> zeiger(80, 40)
>>> pu(); home(); pd()
Okay. Das funktioniert. Jetzt müssen wir eine
passende Zeigerform zu einer verfügbaren
Turtle-Shape machen. Im Direktmodus geht
das leicht:
>
Mach mit!
>>> reset()
>>> begin_poly()
>>> zeiger(130, 25)
>>> end_poly()
>>> zeiger_form = get_poly()
>>> screen.register_shape("sekundenzeiger", zeiger_form)
>>> reset()
>>> shape("sekundenzeiger")
>>> right(1080)
Fein, jetzt haben wir der Turtle Zeigerform gegeben. Wenn wir nun die
Turtle mit
right()
drehen, dann dreht sich der Zeiger. (6° entsprechen
einer Sekunde.) Und so können wir den Zeiger bewegen.
364
Ereignisgesteuerte Programme
Kapitel
13
>>> speed(1)
>>> right(6)
>>> right(6)
>>> for i in range(58):
right(6)
Fein, das funktioniert auch. Für das Zeichnen des Ziffernblattes und der
Zeigerform haben wir die »anonyme« Turtle verwendet. Da die in Zukunft
nicht die Rolle eines Uhrzeigers übernehmen soll, geben wir ihr wieder eine
normale Gestalt:
>>> shape("turtle")
Als Zeiger (später vielleicht mehrere Zeiger) wollen wir wieder benannte
Objekte der Klasse
Turtle
verwenden. Zunächst einmal eine Turtle namens
sekundenzeiger
. Und weil wir vielleicht mehrere unterschiedliche Zeiger-
formen zu Turtle-Shapes machen wollen, verpacken wir den entsprechenden
Code auch in eine Funktion
mache_zeiger_shape()
mit Parametern für
name
der Turtle-Form sowie
laenge
und
spitze
. Wenn wir uns am obigen
interaktiven Beispiel orientieren, muss diese Funktion so aussehen:
def mache_zeiger_shape(name, laenge, spitze):
reset()
begin_poly()
zeiger(laenge, spitze)
end_poly()
zeiger_form = get_poly()
screen.addshape(name, zeiger_form)
>
Füge diesen Code unterhalb der Funktion
zeiger()
in das Script
uhr_arbeit.py
ein.
In der Funktion
uhr()
können wir jetzt diese Funktion wie folgt benutzen:
def uhr():
global sekundenzeiger
winsize(400, 400)
shape("turtle")
mache_zeiger_shape("sekundenzeiger", 130, 25)
ziffernblatt(160)
sekundenzeiger = Turtle()
sekundenzeiger.shape("sekundenzeiger")
sekundenzeiger.turtlesize(1, 1, 3)
sekundenzeiger.color("red", "blue")
sekundenzeiger.speed(1)

Get Python für Kids now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.