TigerJython xx
für Gymnasien

Computeranimation


Die Computergrafik kann ähnlich wie in einem Film zur Darstellung von zeitlich veränderlichen Inhalten verwendet werden. Man nennt ein so eingesetztes Programm eine Computeranimation. Um den zeitlichen Ablauf sichtbar zu machen, wird in einer Animationsschleife immer nach einem gleich grossen Zeitschritt ein neues Bild gezeichnet, das sich nur wenig vom vorhergehenden unterscheidet. Werden mehr als 25 Bilder pro Sekunde erzeugt, so ergibt sich für das Auge eine fliessende Bewegung.

Das Prinzip der Animation kann man an einer sich scheinbar bewegenden Figur zeigen. Dabei wird die Figur in kurzen Zeitschritten an leicht verschobenen Positionen gezeichnet. Die vorangehende Figur muss du immer wieder gelöscht werden

Im ersten Beispiel läss man einen Propeller rotieren. Für die Wiederholung verwendet man eine endlose while-Schleife. In dieser Animationsschleife zeichnet man zuerst den Propeller. Danach wartet man 50 ms. Diese Wartezeit bestimmt, wie häufig der Propeller pro Sekunde neu gezeichnet wird. Dann löschst man den Bildschirm mit clear() und drehst die Turtle um 10 Grad, damit der nächste Propeller in leicht gedrehter Lage gezeichnet wird.

Für ein ruckelfreie Computeranimation ist es wichtig, dass das Zeichnen in einem Bildspeicher (Bildbuffer) erfolgt und das Bild erst nachher als Ganzes auf dem Bildschirm dargestellt ("gerendert") wird. Diese Art des Zeichnens nennt man auch Doppelbufferung.

 

 

# Tu15a.py

from gturtle import *

def propeller():
    repeat 3:
        fillToPoint()    
        rightArc(100, 90)
        right(90)
        rightArc(100, 90)
        left(30)       
    
makeTurtle()
hideTurtle()
enableRepaint(False)

while True:         
    propeller() 
    repaint()  
    delay(40)
    clear()     
    right(10)  
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

def propeler(): zeichnet den Propeller
enableRepaint(False): das automatische Render der Bildschirmspeichers auf den Bildschirm wird deaktiviert, um das Flattern zu vermeinden
repaint(): Inhalt des Bildschirmspeichers wird auf dem Bildschirm angezeigt (gerendert)
delay(40): 40 Millisekunden warten
clear: Bildschirm löschen

 

Beispiel 2: PingPong
In einem Ping-Pong-Spiel will man den roten Ball zwischen den grünen Balken hin und her bewegen.

# Tu15b.py

from gturtle import *

def wall():
    setPenColor("green")
    setPenWidth(10)
    setPos(-200, -50)
    forward(100)
    setPos(200, -50)
    forward(100)    

makeTurtle()
hideTurtle()
enableRepaint(False)

x = -170
dx = 10

while True:
    clear()
    wall()
    setPos(x, 0)
    setPenColor("red")
    dot(60)
    repaint()
    x = x + dx
    if x > 165 or x < -165:
        dx = -dx      
    delay(40) 
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)
 

 

Erklärungen zum Programmcode:

if x > 165 or x < -165: Der Ball ist an linken oder rechten Balken angekommen

dx = .-dx: Wenn dx das Vorzeichen wechselt, bewegt sich der Ball in der umgekehrten Richtung

Beispiel 3: Flügelbewegungen eines Vogels
Der Vogel. Dieser besteht der Einfachheit halber aus einem runden Körper und zwei Kreisbögen, die links und rechts vom Körper gezeichnet werden. Um die Lage der Flügel einzustellen,  dreht man die Turtle vor dem Zeichnen des Flügels in die passende Richtung. Die Funktion bird(angle) hat daher einen Parameter angle, der die Turtle-Richtung vor dem Zeichnen der Flügel angibt. Dieser Winkel steigt bei der Abwärtsbewegung von 5° bis 55° und fällt bei der Aufwärtsbewegung von 55° bis 5°.

# Tu15c.py

from gturtle import *

def bird(angle):
    dot(20)
    right(angle)
    rightArc(100, 90)
    home()
    left(angle)
    leftArc(100, 90)
    home()
    
def move(start, end, step):
    for a in range(start, end, step):
        clear("lightSkyBlue")   
        bird(a)
        repaint()
        delay(40) 
    
makeTurtle()
hideTurtle()
setPenWidth(5)
setPenColor("black")
enableRepaint(False)

while True:
    move(55, 5, -2)
    move(5, 55, 2)    
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)
 

 

Erklärungen zum Programmcode:

def move(start, end, step): Da sich die Flügel einmal von oben nach unten und dann von unten nach obe nbewegen, wird eine Funktion move() definiert, die zweimal mit verschiedenen Parametern aufgerugen wird.

 

Beispiel 4: Weihnachtssterne
50 Sterne in zufällig gewählten Farben werden an zufällig gewählten Positionen gezeichnet. Die Sterne bewegen sich langsam nach unten und im oberen Teil des Fensters werden wieder neue Sterne erzeugt.

Die 50 Sterne werden in einer repeat-Schleife erzeugt und ihre zufällige Position und zufällige Farbei in einer Liste sky gespeichert. Um die Sterne nach unten zu bewegen, wird eine zweite Liste skyTemp erstellt. In der Animationsschleife werden zuerst alle Sterne der Liste sky gezeichnet. Danach wird für jeden Stern aus der Liste sky die y-Koordinate um 1 verkleinert und x, y, und c in der Liste skyTemp gespeichert. Danach wird die Liste sky mit skyTemp ersetzt.

Falls die y-Koordinate kleiner als -340 (der Stern ist im Fenster nicht mehr sichtbar), wird die y-Koordinate auf 320 gesetzt (der Stern erscheint wieder oben.

 



# Tu15d.py

from gturtle import *
from random import randint

def star():
    startPath()
    repeat 5:
        forward(40)
        right(144)  
    fillPath()
    
def drawSky():
    clear("darkblue")
    for (x, y, c) in sky:
        setPenColor(c)
        setFillColor(c)
        setPos(x, y)
        star()  
                                
makeTurtle()        
hideTurtle()
sky = []
enableRepaint(False)

repeat(50):
    x = randint (-270, 270)
    y = randint (-320, 320) 
    c = makeColor(randint(0, 255), randint(0, 255), randint(0, 255))
    sky.append((x, y, c))
    
while True:
    drawSky()
    repaint()
    skyTemp = []
    for (x, y, c) in sky:
        if y < -340:
            y = 320
        else:    
            y -= 1
        skyTemp.append((x, y, c))
    sky = skyTemp    
    delay(20)
    
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

sky.append((x, y, c)) :die Koordinaten x und y, sowie die zufällige Farbe werden in der Liste sky gespeichert

enableRepaint(False) :verhindert das automatische Zeichnen jedes Sternes

drawSky()
repaint()
alle Sterne der Liste sky werden auf einmal gezeichnet, wobei das ganze Fenster vorher mit der dunkelblauen Farbe übermalt wird


Beispiel 5: Animierte Bilder
Eine Turtle kann als Leitfigur sogar Spritebilder bewegen. Hier verwendet man 8 Spritebilder, die Bewegungsformen eines laufenden Ponys darstellen (pony_0.gif, pony_1.gif, pony_2.gif, ... pony_7.gif). In der Animationsschleife bewegt sich die Turtle vorwärts und nach jeder Vorwärtsbewegung das nächste Bild angezeigt. Nach dem letzten bild wird die Liste erbeut duchgelaufen.

# Tu15e.py

from gturtle import *

makeTurtle()
hideTurtle()
penUp()
setPos(200, 0)
left(90)
enableRepaint(False)
wrap()

img = ["sprites/pony_0.gif", "sprites/pony_1.gif", "sprites/pony_2.gif",
       "sprites/pony_3.gif", "sprites/pony_4.gif", "sprites/pony_5.gif",
       "sprites/pony_6.gif", "sprites/pony_7.gif"] 
repeat:
    for i in img:
        drawImage(i)
        repaint()
        delay(100)
        clear()
        forward(5)
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)
 

 

Erklärungen zum Programmcode:

drawImage(i): Stellt das i-te Bild an der aktuellen Position dar
wrap() : wenn sich die Turtle ausserhalb des Fensters befindet, wird sie automatisch auf die andere Seite zurückversetzt


Beispiel 6: Mehrere Objekte animieren
Da wir mehrere Turtles erzeugen können, können wir auch zwei Ponys gleichzeitig laufen lassen. Die beide Turtles werden im gleiner TurtleFrage erzeugt und an verschiedene Startpositionen versetzt. Die Listen mit den Spritebildern könnn eleganter mit Hilfe einer for-Schleife zusammengestellt werden. Alle 16 Spritebilder sind in der TigerJython-Distribution enthalten.

# Tu15f.py

from gturtle import *

tf = TurtleFrame()
t1 = Turtle(tf)
t2 = Turtle(tf)
t1.ht()
t2.ht()
t1.setPos(120, 0)
t2.setPos(250, 0)
t1.left(90)
t2.left(90)
tf.enableRepaint(False)

imgT1 = [0] * 8
imgT2 = [0] * 8
for i in range(8):
    imgT1[i] = "sprites/pony_" + str(i) + ".gif"   
for i in range(8):     
    imgT2[i] = "sprites/pony2_" + str(i) + ".gif"  

repeat:
    for i in range(8):
        t1.drawImage(imgT1[i])
        t2.drawImage(imgT2[i])
        tf.repaint()
        tf.delay(100)
        tf.clear()
        t1.forward(5)
        t2.forward(5)
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)
 

 

Erklärungen zum Programmcode:

for i in range(8):
imgT1[i] = "sprites/pony_" + str(i) + ".gif"
: Erzeugt eine Liste mit 8 Spritebildern


Beispiel 7: Spritebilder spiegeln
Die Bilder, die du mit drawImage("bilddatei") zeichnest, erscheinen an der aktuellen Position der Turtle und ihre Drehrichtung entspricht der Blickrichtung der Turtle. Manchmal muss man an die Bilder spiegeln. Dazu verwendet man in drawImage() zwei zusätzliche Parameter:

 drawImage("bilddatei", True, False)  horizontale Spiegelung
 drawImage("bilddatei", False, True)  vertikale Spiegelung
 drawImage("bilddatei", True, True)  horizontale und vertikale Spiegelung
# Tu15g.py

from gturtle import *

tf = TurtleFrame()
t1 = Turtle(tf)
t2 = Turtle(tf)
t1.ht()
t2.ht()
t1.setPos(250, 0)
t2.setPos(-250, 0)
t1.left(90)
t2.right(90)
t1.wrap()
t2.wrap()
tf.enableRepaint(False)

imgT1 = [0] * 8
imgT2 = [0] * 8
for i in range(8):
    imgT1[i] = "sprites/pony_" + str(i) + ".gif"   
for i in range(8):     
    imgT2[i] = "sprites/pony2_" + str(i) + ".gif"  

repeat:
    for i in range(8):
        t1.drawImage(imgT1[i])
        t2.drawImage(imgT2[i], False, True)
        tf.repaint()
        tf.delay(100)
        tf.clear()
        t1.forward(5)
        t2.forward(5)
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)
 

 

Erklärungen zum Programmcode:

t2.drawImage(imgT2[i], False, True): Die Images werden vertikal gespiegelt  

 


Aufgaben Serie 15

1)

Definiere eine Funktion rad(), die ein Velo Rad mit 12  Speichen zeichnet, wie in der Abbildung. Für das Zeichnen der Veloreife kannst du den Befehl dot() verwenden (zuerst schwarz, dann etwas kleiner weiss). Erstelle eine Animation, bei der das Rad um die eigene Achse am Ort dreht. 

 

       
2)

Zeichne einen quadratischen oder rechteckigen Billardtisch. Eine Billardkugelbewegt sich so, dass sie an den Rändern jeweils unter der Berücksichtigung der Regel Einfallswinkel = Ausfallswinkel reflektiert wird. Damit du den Billardtisch in der Animationsschleife nicht immer neu zeichnen musst, ist es hier einfacher den roten Kreis an der alten Position jeweils mit der weissen Farbe zu übermalen.

 
       
3)

Zeichne eine Fahne und schwenke sie um den untersten Punkt der Fahnenstange hinauf und hinunter.

 
       
4)

Stelle mit den 5 Bildern
person_0.png, person_1.png, person_2.png,
person_3.png und person_4.png
eine von links nach rechts laufende Person dar.

 

 

 
       
5)

Stelle mit den gleichen 5 Bildern
eine von rechts nach links laufende Person dar.

 

 

 
       
6)

Verwende zusätzlich die Sprites
tiger_2.gif, tiger_3.gif, tiger_4.gif, tiger_5.gif, tiger_6.gif
und erstelle eine Animation, bei der eine Person und ein Tiger gegeneinander laufen.

 

 

7)

Zeichne eine absteigende Treppe mit 10 Stufen. Ein roter Ball startet auf der obersten Stufe und bewegt sich Tritt nach Tritt nach unten.

Um diese Animation zu programmieren, ist es sinnvoll folgende Funktionen zu definieren:  Funktion step(), welcher eine Stufe zeichnet, Funktion treppe(), der die ganze Treppe zeichnet und Funktion ball(), die den roten Ball zeichnet. Bevor du den Ball jeweils an einer neuen Position zeichnest, lasse ihn an der alten Position verschwinden, in dem du ihn mit einem weissen Kreis übermalst. Dadurch muss du nicht jeweils das ganze Fenster löschen und die Treppe immer wieder neu zeichnen.