- Felder und Methoden in Game und Editor typisiert - Tilemap: Felder, render, tiles_around, physics_rects_around, autotile - Animation: Konstruktor-Parameter, Felder, copy und update - Clouds: Cloud und Clouds vollstaendig typisiert - utils: load_image und load_images mit Rueckgabe-Typ
128 lines
4.3 KiB
Python
128 lines
4.3 KiB
Python
class Animation:
|
|
def __init__(self, images: list, image_duration: int = 5, loop: bool = True):
|
|
"""
|
|
Initialisiert eine Animation mit einer Liste von Bildern.
|
|
|
|
Anforderungen (damit die Tests bestehen):
|
|
- images speichern
|
|
- image_duration speichern
|
|
- loop speichern
|
|
- frame startet bei 0
|
|
- done startet bei False
|
|
"""
|
|
# TODO: Implementieren
|
|
self.images: list = images
|
|
self.image_duration: int = image_duration
|
|
self.loop: bool = loop
|
|
self.frame: int = 0
|
|
self.done: bool = False
|
|
|
|
def copy(self) -> "Animation":
|
|
"""
|
|
Erstellt eine Kopie der Animation.
|
|
|
|
Anforderungen:
|
|
- Rückgabewert ist ein neues Animation-Objekt (nicht dasselbe Objekt)
|
|
- gleiche images / image_duration / loop
|
|
- neue Animation startet wieder bei frame = 0 und done = False
|
|
"""
|
|
# TODO: Implementieren
|
|
copy_animation = Animation(self.images, self.image_duration, self.loop)
|
|
return copy_animation
|
|
|
|
def update(self) -> None:
|
|
"""
|
|
Aktualisiert die Animation um einen Frame weiter.
|
|
|
|
Anforderungen:
|
|
- Wenn loop=True:
|
|
frame wird erhöht und springt am Ende wieder auf 0
|
|
- Wenn loop=False:
|
|
frame wird erhöht, aber bleibt am Ende stehen
|
|
done wird True, sobald das letzte Bild erreicht ist (siehe Tests)
|
|
"""
|
|
# TODO: Implementieren
|
|
# SCHRITT A: Modulo (Der Loop-Trick)
|
|
# Sorgt dafür, dass wir nie über 14 hinausgehen (0 bis 14)
|
|
if self.loop:
|
|
gesamt_dauer = len(self.images) * self.image_duration # 5 * 5 = 25 Frames pro Durchlauf
|
|
self.frame = (self.frame+1) % gesamt_dauer
|
|
else:
|
|
self.frame = min(self.frame + 1, len(self.images) * self.image_duration -1)
|
|
if self.frame >= self.image_duration * (len(self.images) - 1):
|
|
self.done = True
|
|
|
|
def img(self):
|
|
"""
|
|
Gibt das aktuelle Bild der Animation zurück.
|
|
|
|
Anforderungen:
|
|
- Das aktuelle Bild hängt von frame und image_duration ab.
|
|
- Beispiel: image_duration=2
|
|
frame 0,1 -> images[0]
|
|
frame 2,3 -> images[1]
|
|
frame 4,5 -> images[2]
|
|
"""
|
|
# TODO: Implementieren
|
|
""" Gibt das aktuelle Bild der Animation zurück. """
|
|
return self.images[int(self.frame / self.image_duration)]
|
|
|
|
if __name__ == "__main__":
|
|
|
|
import unittest
|
|
|
|
class TestAnimation(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.images = ["img1", "img2", "img3"]
|
|
|
|
def test_initialization(self):
|
|
anim = Animation(self.images, image_duration=2, loop=False)
|
|
self.assertEqual(anim.images, self.images)
|
|
self.assertEqual(anim.image_duration, 2)
|
|
self.assertFalse(anim.loop)
|
|
self.assertEqual(anim.frame, 0)
|
|
self.assertFalse(anim.done)
|
|
|
|
def test_copy(self):
|
|
anim = Animation(self.images, image_duration=3, loop=False)
|
|
anim_copy = anim.copy()
|
|
|
|
self.assertIsNot(anim, anim_copy)
|
|
self.assertEqual(anim_copy.images, self.images)
|
|
self.assertEqual(anim_copy.image_duration, 3)
|
|
self.assertFalse(anim_copy.loop)
|
|
self.assertEqual(anim_copy.frame, 0)
|
|
|
|
def test_looping_update(self):
|
|
anim = Animation(self.images, image_duration=1, loop=True)
|
|
|
|
for _ in range(3):
|
|
anim.update()
|
|
|
|
# 3 Bilder * 1 Frame pro Bild = 3 Frames total -> wieder bei 0
|
|
self.assertEqual(anim.frame, 0)
|
|
|
|
def test_non_looping_update_and_done(self):
|
|
anim = Animation(self.images, image_duration=1, loop=False)
|
|
|
|
anim.update()
|
|
anim.update()
|
|
anim.update()
|
|
|
|
# Ohne Loop bleibt er beim letzten Frame (2) stehen
|
|
# und done soll True sein (siehe Logik in der Aufgabenbeschreibung)
|
|
self.assertTrue(anim.done)
|
|
self.assertEqual(anim.frame, 2)
|
|
|
|
def test_img_selection(self):
|
|
anim = Animation(self.images, image_duration=2, loop=True)
|
|
|
|
anim.update() # frame 1
|
|
self.assertEqual(anim.img(), "img1")
|
|
|
|
anim.update() # frame 2
|
|
self.assertEqual(anim.img(), "img2")
|
|
|
|
|
|
unittest.main()
|