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:

  1. 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() und random.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.
  1. 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 *  # [!code ++]
from ship import *  # [!code ++]

# Wir kontrollieren das Fenster selbst [!code --]
window = turtle.Screen() # [!code --]
window.setup(0.5, 0.75) # Breite und Höhe relativ zum Bildschirm [!code --]
window.bgcolor("#202020") # Hintergrund in Hex-RGB [!code --]
window.title("Turtle Invaders") # Titel des Fensters [!code --]
window.tracer(0) # [!code --]

# Einige Konstanten fĂŒr das Fenster, die uns hilfreich sein werden [!code --]
LEFT = -window.window_width() / 2  # [!code --]
RIGHT = window.window_width() / 2  # [!code --]
TOP = window.window_height() / 2  # [!code --]
BOTTOM = -window.window_height() / 2  # [!code --]
GROUND = 0.9 * BOTTOM  # [!code --]

# Unser Raumschiff [!code --]
SHIP_STEP = 1 # Schrittweite fĂŒr das Raumschiff [!code --]
ship = turtle.Turtle() # [!code --]
turtle.register_shape('spaceship.gif') # [!code --]
ship.shape('spaceship.gif') # [!code --]
ship.penup() # Das Raumschiff soll nichts zeichnen [!code --]
ship.setposition(0, GROUND) # Das Raumschiff soll unten im Bild sein [!code --]

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  # [!code ++]

# 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  # [!code ++]
from window import GROUND  # [!code ++]

# 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.

PythonLoading editor

import turtle
import random

invaderliste = []

for i in range(10):
    invaderliste.append(turtle.Turtle())

for invader in invaderliste:
    invader.right(random.randint(0,360))
    invader.forward(200)

turtle.done()

Code

Was wir in main.py hinzugefĂŒgt haben.

import turtle
from window import *
from ship import *
import time
import random  # [!code ++]

# 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  #  [!code ++]
invader_liste = []  # [!code ++]
invader_time = time.time()  # [!code ++]
INVADER_INTERVALL = 0.5  # [!code ++]
INVADER_SPEED = 2  # [!code ++]
  # [!code ++]
def create_invader():  # [!code ++]
    t = turtle.Turtle()  # [!code ++]
    t.penup()  # [!code ++]
    t.shape("turtle")  # [!code ++]
    t.shapesize(1.5)  # [!code ++]
    t.color("white")  # [!code ++]
    # Zufallsposition [!code ++]
    t.setposition(random.randint(int(LEFT), int(RIGHT)), TOP) # [!code ++]
    t.setheading(-90) # [!code ++]
    # Zufallsfarbe [!code ++]
    t.color(random.random(), random.random(), random.random())  # [!code ++]
    invader_liste.append(t)  # [!code ++]

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:  # [!code ++]
        create_invader()  # [!code ++]
        invader_time = time.time()  # [!code ++]
    for invader in invader_liste:  # [!code ++]
        invader.forward(INVADER_SPEED)  # [!code ++]

    window.update()
    time.sleep(0.001)  # TemporÀre Lösung, um die Animation zu verlangsamen