Lernziele
Es wird nicht erwartet, dass Sie unseren Code oder die verwendeten Befehle auswendig aufschreiben können. Es geht darum, die Logik unserer Lösung und die besprochene Theorie zu verstehen. Insbesondere:
- Sie verstehen unseren Code, könnten Schlüsselstellen erklären, und kurze Teile davon reproduzieren, wenn Sie alle nötigen Befehle erhalten. Spezifisch:
- Sie verstehen, wie wir mit
time.time()
ein Zeitintervall programmiert haben.- Sie können
random.random()
undrandom.randint(a,b)
charakterisieren und sinnvoll einsetzen.- Sie könnten 10 unbenannte Turtle in eine Liste laden, dann die Liste durchiterieren und die Turtles zufällig bewegen.
- Sie verstehen theoretische Konzepte:
- Sie wissen, dass Listen ein strukturierter Datentyp und mutable sind.
Code in mehreren Dateien organisieren
Erklärvideo
Code
import turtle
import time
from window import *
from ship import *
# Wir kontrollieren das Fenster selbst
window = turtle.Screen()
window.setup(0.5, 0.75) # Breite und Höhe relativ zum Bildschirm
window.bgcolor("#202020") # Hintergrund in Hex-RGB
window.title("Turtle Invaders") # Titel des Fensters
window.tracer(0)
# Einige Konstanten für das Fenster, die uns hilfreich sein werden
LEFT = -window.window_width() / 2
RIGHT = window.window_width() / 2
TOP = window.window_height() / 2
BOTTOM = -window.window_height() / 2
GROUND = 0.9 * BOTTOM
# Unser Raumschiff
SHIP_STEP = 1 # Schrittweite für das Raumschiff
ship = turtle.Turtle()
turtle.register_shape('spaceship.gif')
ship.shape('spaceship.gif')
ship.penup() # Das Raumschiff soll nichts zeichnen
ship.setposition(0, GROUND) # Das Raumschiff soll unten im Bild sein
ship_direction = 0 # -1 = nach links, 0 = halt, +1 = nach rechts
# Steuerung
def quit():
global running
running = False
def move_left():
global ship_direction
ship_direction = -1
def move_right():
global ship_direction
ship_direction = 1
def stop_moving():
global ship_direction
ship_direction = 0
window.onkeypress(quit, "q")
window.onkeypress(move_left, "Left")
window.onkeypress(move_right, "Right")
window.onkeyrelease(stop_moving, "Left")
window.onkeyrelease(stop_moving, "Right")
window.listen()
running = True
while running:
new_x = ship.xcor() + SHIP_STEP * ship_direction
if LEFT < new_x < RIGHT:
ship.setx(new_x)
window.update()
time.sleep(.001) # Temporäre Lösung, um die Animation zu verlangsamen
import turtle
# Wir kontrollieren das Fenster selbst
window = turtle.Screen()
window.setup(0.5, 0.75) # Breite und Höhe relativ zum Bildschirm
window.bgcolor("#202020") # Hintergrund in Hex-RGB
window.title("Turtle Invaders") # Titel des Fensters
window.tracer(0)
# Einige Konstanten für das Fenster, die uns hilfreich sein werden
LEFT = -window.window_width() / 2
RIGHT = window.window_width() / 2
TOP = window.window_height() / 2
BOTTOM = -window.window_height() / 2
GROUND = 0.9 * BOTTOM
import turtle
from window import GROUND
# Unser Raumschiff
SHIP_STEP = 1 # Schrittweite für das Raumschiff
ship = turtle.Turtle()
turtle.register_shape('spaceship.gif')
ship.shape('spaceship.gif')
ship.penup() # Das Raumschiff soll nichts zeichnen
ship.setposition(0, GROUND) # Das Raumschiff soll unten im Bild sein
Die Turtleinvader kommen!
Erklärvideo
Zeitintervall
Die Funktion time()
aus dem Paket time
gibt uns die aktuelle Zeit in Sekunden seit 00:00 am 1. Januar 1970 in der Standardzeit UTC. Das ist für Sie allerdings wenig relevant, weil Sie werden time.time()
immer als Differenz zwischen zwei Zeitpunkten nutzen. Wichtig also: Die Differenz wird in Sekunden gemessen.
Hier ein simplifizierter Auszug.
import time
INVADER_INTERVALL = 1 # in Sekunden
invader_time = time.time()
running = True
while running:
# ...
# Wenn die Zeitdifferenz das Interval überschreitet
if (time.time() - invader_time) > INVADER_INTERVALL:
# Neuen Turtleinvader kreieren
# ...
# Setze den Zeitstempfel neu für das nächste Intervall
invader_time = time.time()
# ...
Anonyme Turtle in Listen
Wir fügen unserer Liste jeweils eine Turtle hinzu.
import turtle
turtleliste = []
def create_invader():
t = turtle.Turtle()
# Turlte konfigurieren und stylen
turtleliste.append(t)
# Funktion ausführen
create_invader()
create_invader()
# Zum Verständnis drucken wir die Liste aus
print(turtleliste)
Im Speicher passiert dabei Folgendes:
- Die Liste speichert Verweise auf die verschiedenen Turtle-Objekte im Speicher, die von turtle.Turtle() kreiert werden.
- Wenn wir durch
turtleliste
iterieren, können wir mit der Laufvariable die verschiedenen Turtle-Objekte bewegen.
Zufallszahlen
Das Paket random
bietet einige Möglichkeiten, Zufallszahlen zu generieren. Wir verwenden zwei Funktionen davon:
random.random()
generiert eine Fliesskomma-Zufallszahl zwischen 0 und 1.random.randint(a,b)
generiert eine Ganzzahl zwischen a und b (inklusiv a und b).
import random
zufallszahlen = []
for i in range(10):
# Ersetzen Sie random.random() zum Vergleich mit random.randint(-300,300)
zufallszahlen.append(random.random())
for zahl in zufallszahlen:
print(zahl)
Turtle zufällig bewegen
Jetzt verbinden wir die gelernten Muster, um eine Liste mit Turtle zu füllen, und sie zufällig zu bewegen.
Code
Was wir in main.py
hinzugefügt haben.
import turtle
from window import *
from ship import *
import time
import random
# Steuerung
ship_direction = 0 # -1 = nach links, 0 = halt, +1 = nach rechts
def quit():
global running
running = False
def move_left():
global ship_direction
ship_direction = -1
def move_right():
global ship_direction
ship_direction = 1
def stop_moving():
global ship_direction
ship_direction = 0
window.onkeypress(quit, "q")
window.onkeypress(move_left, "Left")
window.onkeypress(move_right, "Right")
window.onkeyrelease(stop_moving, "Left")
window.onkeyrelease(stop_moving, "Right")
window.listen()
# Turtle invaders
invader_liste = []
invader_time = time.time()
INVADER_INTERVALL = 0.5
INVADER_SPEED = 2
def create_invader():
t = turtle.Turtle()
t.penup()
t.shape("turtle")
t.shapesize(1.5)
t.color("white")
# Zufallsposition
t.setposition(random.randint(int(LEFT), int(RIGHT)), TOP)
t.setheading(-90)
# Zufallsfarbe
t.color(random.random(), random.random(), random.random())
invader_liste.append(t)
running = True
while running:
new_x = ship.xcor() + SHIP_STEP * ship_direction
if LEFT < new_x < RIGHT:
ship.setx(new_x)
if (time.time() - invader_time) > INVADER_INTERVALL:
create_invader()
invader_time = time.time()
for invader in invader_liste:
invader.forward(INVADER_SPEED)
window.update()
time.sleep(0.001) # Temporäre Lösung, um die Animation zu verlangsamen