EINFÜHRUNG |
In der Natur ist eine Schildkröte ein Individuum mit seiner ganz spezifischen Identität. In einem Zoogehege könntest du jeder Schildkröte einen eigenen Namen geben, z.B. Pepe oder Maya. Schildkröten habe aber auch Gemeinsamkeiten: Sie sind Lebewesen aus der Tierklasse der Schildkröten. Solche Beschreibungen haben sich derart gut bewährt, dass sie in der Informatik als grundlegendes Konzept eingeführt wurden, das sich Objektorientierte Programmierung (OOP) nennt. Mit der Turtlegrafik ist es für dich spielerisch leicht, die Grundprinzipien der OOP kennen zu lernen. |
TURTLEOBJEKT ERZEUGEN |
Bei der bisher verwendeten Turtle handelt es sich um ein anonymes Objekt, für das wir keinen Namen brauchten. Wenn du mehrere Turtles gleichzeitig verwenden willst, musst du aber jeder Turtle mit einem Namen eine eigene Identität geben. Den Namen kannst du als Variablennamen verwenden. Mit der Anweisung maya = Turtle() erzeugst du eine Turtle mit dem Namen maya.
from gturtle import * maya = Turtle() maya.setColor("red") maya.setPenColor("green") maya.setPos(0, -200) repeat 7: repeat 4: maya.forward(50) maya.right(90) maya.forward(50)
|
MEMO |
Gleichartige Objekte werden in Klassen zusammengefasst. Ein Objekt einer Klasse wird erzeugt, indem man den Klassennamen mit einer Parameterklammer verwendet. Wir nennen dies den Konstruktor der Klasse. Funktionen, die zu einer bestimmten Klasse gehören, nennen wir in Zukunft Methoden. |
MEHRERE TURTLEOBJEKTE ERZEUGEN |
Es liegt ja nun auf der Hand, dass du auf die beschriebene Art im gleichen Programm mehrere Turtles verwenden kannst. Willst du maya und pepe erzeugen, so schreibst du
from gturtle import * tf = TurtleFrame() maya = Turtle(tf) maya.setColor("red") maya.setPenColor("red") maya.setPos(0, -200) pepe = Turtle(tf) pepe.setColor("black") pepe.setPenColor("black") pepe.setPos(200, 0) pepe.left(90) repeat 7: repeat 4: maya.forward(50) maya.right(90) pepe.forward(50) pepe.left(90) maya.forward(50) pepe.forward(50) |
MEMO |
Wenn du mehrere Turtles in das gleiche Fenster setzen willst, musst du ein TurtleFrame erzeugen und dieses als Konstruktorparameter der Turtle angeben. Die Turtles kollidieren nicht miteinander, sondern bewegen sich sozusagen übereinander, wobei die eben sich bewegende Turtle immer über allen anderen zu liegen kommt. |
TURTLEPARAMETER |
from gturtle import * def step(t): repeat 4: t.forward(50) t.right(90) t.forward(50) tf = TurtleFrame() maya = Turtle(tf, "sprites/beetle.gif") maya.setPenColor("green") maya.setPos(0, -150) pepe = Turtle(tf, "sprites/cuteturtle.gif") pepe.setPos(200, 0) pepe.left(90) repeat 7: step(maya) step(pepe) |
MEMO |
Du kannst für jede Turtle ein eigenes Bild verwenden, wenn du beim Erzeugen der Turtle den Pfad auf die Bilddatei angibst. Hier verwendest du die beiden Bilddateien beetle.gif und cuteturtle.gif, die sich in der Distribution von TigerJython befinden. |
KÄFERPROBLEME MIT GEKLONTER TURTLE |
Beim berühmten Käferproblem [mehr...
Bei den Verfolgungskurven handelt es sich nach dem Mathematiker Du kannst dieses Problem sehr elegant lösen, indem du zuerst mit der namenlosen (globalen) Turtle das Polygon zeichnest und an jeder Ecke ein geklontes Turtleobjekt erstellst. Du wählst hier ein Viereck und erstellst mit clone() die Turtleklons t1, t2, t3, t4. Ein Klone ist ein neues Turtle-Objekt mit identischen Eigenschaften.
from gturtle import * s = 360 makeTurtle() setPos(-s/2, -s/2) def drawLine(a, b): ax = a.getX() ay = a.getY() ah = a.heading() a.moveTo(b.getX(), b.getY()) a.setPos(ax, ay) a.heading(ah) # generate Turtle clone t1 = clone() t1.speed(-1) forward(s) right(90) t2 = clone() t2.speed(-1) forward(s) right(90) t3 = clone() t3.speed(-1) forward(s) right(90) t4 = clone() t4.speed(-1) forward(s) right(90) hideTurtle() while True: t1.setHeading(t1.towards(t2)) t2.setHeading(t2.towards(t3)) t3.setHeading(t3.towards(t4)) t4.setHeading(t4.towards(t1)) drawLine(t1, t2) drawLine(t2, t3) drawLine(t3, t4) drawLine(t4, t1) t1.forward(5) t2.forward(5) t3.forward(5) t4.forward(5) |
MEMO |
Erzeugst du mit clone() aus der globalen Turtel eine neue Turtle, so hat diese die gleiche Position, die gleiche Blickrichtung und die gleiche Farbe (bei Verwendung von benutzerdefinierten Turtlebildern hat sie das gleiche Turtlebild) [mehr... Die Verwendung von Klons entspricht einem modernen Programmierparadigma: der Prototypenbasierten Programmierung] . Die Funktion drawLine() kann vereinfacht werden, wenn man Position und Blickrichtung der Turtle mit pushState() abspeichert und den Zustand mit popState() wieder zurückholt: def drawLine(a, b):
a.pushState()
a.moveTo(b.getX(), b.getY())
a.popState()
Die Verfolgungskurve lässt sich mathematisch berechnen (siehe). |
AUFGABEN |
|
ZUSATZSTOFF |
TURTLES MIT MAUSKLICK ERZEUGEN |
from gturtle import * def drawStar(x, y): t = Turtle(tf) t.setPos(x, y) t.fillToPoint(x, y) for i in range(6): t.forward(40) t.right(140) t.forward(40) t.left(80) tf = TurtleFrame(mouseHit = drawStar) |
MEMO |
In der OOP werden Objekte mit gleichen Fähigkeiten und gleichen Eigenschaften in Klassen zusammengefasst. Mit dem Konstruktor erzeugt man einzelne Objekte (Instanzen). Um einen Mausklick zu verarbeiten, schreibst du eine Funktion mit beliebigem Namen (aber zwei Parametern x und y) und übergibt diesen Funktionsnamen im Konstruktor von TurtleFrame dem benannten Parameter mouseHit. x und y liefern die Koordinaten des Mausklicks. |