From 3d18c9ee4d24dad3f7814e322c16b8d221ba4306 Mon Sep 17 00:00:00 2001 From: schererleander Date: Fri, 26 Dec 2025 22:50:10 +0100 Subject: feat(logic): use delta time for movment of sprites --- Alien.py | 16 +++++++++----- Extra.py | 9 +++++--- Laser.py | 12 ++++++----- Spieler.py | 15 +++++++++---- Steuerung.py | 51 ++++++++++++++++++++++--------------------- Szenen.py | 70 ++++++++++++++++++++++++++++++------------------------------ __init__.py | 1 - 7 files changed, 97 insertions(+), 77 deletions(-) diff --git a/Alien.py b/Alien.py index 5400447..b8ef24e 100644 --- a/Alien.py +++ b/Alien.py @@ -7,9 +7,13 @@ class Alien(pygame.sprite.Sprite): self.image = pygame.image.load(os.path.abspath(bildDateipfad)) self.rect = self.image.get_rect() self.rect.center = position + + self.__pos_x = float(self.rect.x) + self.__pos_y = float(self.rect.y) self.__wert = wert - self.__geschwindigkeit = 1 + # pixels/second (old: 1 px/frame @ 60 FPS) + self.__geschwindigkeit = 60.0 def getRect(self): return self.rect @@ -19,9 +23,11 @@ class Alien(pygame.sprite.Sprite): def aendereRichtung(self): self.__geschwindigkeit *= -1 - - def bewegen(self): - self.rect.x += self.__geschwindigkeit + + def bewegen(self, dt: float): + self.__pos_x += self.__geschwindigkeit * dt + self.rect.x = int(round(self.__pos_x)) def bewegeRunter(self, y): - self.rect.y += y \ No newline at end of file + self.__pos_y += y + self.rect.y = int(round(self.__pos_y)) \ No newline at end of file diff --git a/Extra.py b/Extra.py index edc60a3..82ea6d7 100644 --- a/Extra.py +++ b/Extra.py @@ -8,10 +8,13 @@ class Extra(pygame.sprite.Sprite): self.rect = self.image.get_rect() self.rect.center = (x,y) - self.__geschwindigkeit = 2 + self.__pos_x = float(self.rect.x) + # pixels/second (old: 2 px/frame @ 60 FPS) + self.__geschwindigkeit = 120.0 - def bewegen(self): - self.rect.x = self.rect.x + self.__geschwindigkeit + def bewegen(self, dt: float): + self.__pos_x += self.__geschwindigkeit * dt + self.rect.x = int(round(self.__pos_x)) def einschraenken(self, screenLaenge): if self.rect.left >= screenLaenge: diff --git a/Laser.py b/Laser.py index 18503d0..ab7b9a4 100644 --- a/Laser.py +++ b/Laser.py @@ -1,17 +1,19 @@ import pygame class Laser(pygame.sprite.Sprite): - def __init__(self, position: tuple, geschwindigkeit: str): + def __init__(self, position: tuple, geschwindigkeit: float): super().__init__() self.image = pygame.Surface((3,10)) self.image.fill((255,255,255)) # Farbe self.rect = self.image.get_rect() self.rect.center = position - - self.__geschwindigkeit = geschwindigkeit + + self.__pos_y = float(self.rect.y) + self.__geschwindigkeit = float(geschwindigkeit) def getRect(self): return self.rect - def bewegen(self): - self.rect.y += self.__geschwindigkeit \ No newline at end of file + def bewegen(self, dt: float): + self.__pos_y += self.__geschwindigkeit * dt + self.rect.y = int(round(self.__pos_y)) \ No newline at end of file diff --git a/Spieler.py b/Spieler.py index 0c2f362..e365970 100644 --- a/Spieler.py +++ b/Spieler.py @@ -8,8 +8,11 @@ class Spieler(pygame.sprite.Sprite): self.rect = self.image.get_rect() self.rect.center = position + self.__pos_x = float(self.rect.x) + self.__leben = 3 - self.__geschwindigkeit = 8 + # pixels/second (old: 8 px/frame @ 60 FPS) + self.__geschwindigkeit = 480.0 self.__laserCoolDown = 300 self.__zeitVonLetzenSchuss = 0 @@ -20,18 +23,22 @@ class Spieler(pygame.sprite.Sprite): def getLeben(self) -> int: return self.__leben - def bewegen(self): + def bewegen(self, dt: float): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: - self.rect.x -= self.__geschwindigkeit + self.__pos_x -= self.__geschwindigkeit * dt if keys[pygame.K_RIGHT]: - self.rect.x += self.__geschwindigkeit + self.__pos_x += self.__geschwindigkeit * dt + + self.rect.x = int(round(self.__pos_x)) def einschraenken(self, screenLaenge): if self.rect.left <= 0: self.rect.x = 0 if self.rect.right >= screenLaenge: self.rect.right = screenLaenge + + self.__pos_x = float(self.rect.x) def schuss(self): keys = pygame.key.get_pressed() diff --git a/Steuerung.py b/Steuerung.py index 7f0a592..8356aeb 100644 --- a/Steuerung.py +++ b/Steuerung.py @@ -1,13 +1,17 @@ import pygame from Szenen import * + class Steuerung(): def __init__(self): self.__szene = Menue() self.__szenenIndex = 0 self.__verlasseSpiel = False self.__spielerListe = [] - self.__loop() + + self.__clock = pygame.time.Clock() + + self.loop() def __sotiereSpielerListe(self): self.__spielerListe.sort(key=lambda spieler: spieler[1], reverse=True) @@ -17,35 +21,34 @@ class Steuerung(): for spieler in range(len(self.__spielerListe)): if self.__spielerListe[spieler][0] == spielerName: gibtSpieler = True - self.__spielerListe[spieler][1] = spielerScore + self.__spielerListe[spieler] = (spielerName, spielerScore) if not gibtSpieler: self.__spielerListe.append((spielerName, spielerScore)) - def __verlasseSpiel(self): - self.__verlasseSpiel = True - def __wechselSzene(self): self.__szenenIndex += 1 if self.__szenenIndex > 3: self.__szenenIndex = 0 - match(self.__szenenIndex): - case 0: - self.__szene = Menue() - case 1: - self.__szene = Game() - case 2: - score = self.__szene.getScore() - self.__szene = Benennung(score) - case 3: - score = self.__szene.getScore() - name = self.__szene.getName() - self.__addSpieler(name, score) - self.__sotiereSpielerListe() - self.__szene = Score(self.__spielerListe) - - - def __loop(self): + + if self.__szenenIndex == 0: + self.__szene = Menue() + elif self.__szenenIndex == 1: + self.__szene = Game() + elif self.__szenenIndex == 2: + score = self.__szene.getScore() + self.__szene = Benennung(score) + elif self.__szenenIndex == 3: + score = self.__szene.getScore() + name = self.__szene.getName() + self.__addSpieler(name, score) + self.__sotiereSpielerListe() + self.__szene = Score(self.__spielerListe) + + + def loop(self): while not self.__szene == None and not self.__verlasseSpiel: + dt = self.__clock.tick(60) / 1000.0 + events = [] for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -54,9 +57,9 @@ class Steuerung(): events.append(event) self.__szene.beiEingabe(events) - self.__szene.beiUpdate() + self.__szene.beiUpdate(dt) self.__szene.beiZeichne() if self.__szene.getWechselSzene(): - self.__wechselSzene() \ No newline at end of file + self.__wechselSzene() diff --git a/Szenen.py b/Szenen.py index 58b139d..99e937a 100644 --- a/Szenen.py +++ b/Szenen.py @@ -7,8 +7,8 @@ class Szene(): def beiEingabe(self, events: list): pass - def beiUpdate(self): - pass + def beiUpdate(self, dt: float): + pass def beiZeichne(self): pass @@ -35,13 +35,16 @@ class Menue(Szene): if keys[pygame.K_SPACE]: self._wechselSzene = True + def beiUpdate(self, dt: float): + pass + def beiZeichne(self): # Der Hintergrund wird auf den Screen gezeichnet self.__screen.blit(self.__background, (0,0)) - self.__dieGUI.zeichneText('Space Invaders', 20, self.__screen.get_width()/2, self.__screen.get_height()*0.20, (255,255,255)) - self.__dieGUI.zeichneText('Um das Spiel zu starten druecke:', 16, self.__screen.get_width()/2, self.__screen.get_height()*0.40, (255,255,255)) - self.__dieGUI.zeichneRoundedButton('Space', 15,self.__screen.get_width()/2, self.__screen.get_height()*0.60, 120, 60, 10, (255,255,255), (0,0,0)) + self.__dieGUI.zeichneText('Space Invaders', 20, self.__screen.get_width()//2, int(self.__screen.get_height()*0.20), (255,255,255)) + self.__dieGUI.zeichneText('Um das Spiel zu starten druecke:', 16, self.__screen.get_width()//2, int(self.__screen.get_height()*0.40), (255,255,255)) + self.__dieGUI.zeichneRoundedButton('Space', 15, self.__screen.get_width()//2, int(self.__screen.get_height()*0.60), 120, 60, 10, (255,255,255), (0,0,0)) # Das Bild wird refreshed pygame.display.flip() @@ -57,7 +60,6 @@ class Game(Szene): def __init__(self): super().__init__() self.__screen = pygame.display.set_mode((600,700)) - self.__clock = pygame.time.Clock() self.__hintergrund = pygame.Surface((self.__screen.get_width(), self.__screen.get_height())) self.__hintergrund.fill((0,0,0)) @@ -78,7 +80,7 @@ class Game(Szene): self.__spielerTodSound = pygame.mixer.Sound('assets/sound/explosion.wav') self.__spielerTodSound.set_volume(self.__volume) - self.__derSpieler = Spieler((self.__screen.get_width()/2, self.__screen.get_height()*0.90)) + self.__derSpieler = Spieler((int(self.__screen.get_width()/2), int(self.__screen.get_height()*0.90))) self.__dieGUI = GUI(self.__screen) self.__spielerSpriteGruppe = pygame.sprite.GroupSingle(self.__derSpieler) @@ -97,7 +99,7 @@ class Game(Szene): 'xx xx', ] - self.__erstelleAlleBunker(anzahl=4,groeße=7,startX=50,startY=self.__screen.get_width()*0.85, xOffset=80) + self.__erstelleAlleBunker(anzahl=4,groeße=7,startX=50,startY=int(self.__screen.get_width()*0.85), xOffset=80) self.__erstelleAliens(zeilen=6,spalten=8,startX=50, startY=100,xDistanz=20,yDistanz=20) def __erstelleBunker(self, groeße: int, startX: int, startY: int): @@ -128,13 +130,13 @@ class Game(Szene): dasAlien = Alien('assets/img/yellow.png', (x, y), 60) elif zeile == 1 or zeile == 2: dasAlien = Alien('assets/img/green.png', (x, y), 30) - elif zeile == 3 or zeile == 4 or zeile == 5: + else: dasAlien = Alien('assets/img/red.png', (x, y), 20) self.__alienSpriteGruppe.add(dasAlien) - def __bewegeAliens(self): + def __bewegeAliens(self, dt: float): for alien in self.__alienSpriteGruppe: - alien.bewegen() + alien.bewegen(dt) if alien.getRect().right >= self.__screen.get_width(): for alien in self.__alienSpriteGruppe: alien.aendereRichtung() @@ -151,7 +153,7 @@ class Game(Szene): randomAlien = alienListe[randrange(len(alienListe))] self.__zeitVonLetztenAlienSchuss = pygame.time.get_ticks() self.__shootSound.play() - self.__alienLaserSpriteGruppe.add(Laser((randomAlien.getRect().centerx, randomAlien.getRect().bottom), 2)) + self.__alienLaserSpriteGruppe.add(Laser((randomAlien.getRect().centerx, randomAlien.getRect().bottom), 120.0)) def __erstelleExtra(self): jetzt = pygame.time.get_ticks() @@ -159,9 +161,9 @@ class Game(Szene): self.__extraSpriteGruppe.add(Extra(-10, 50)) self.__zeitvonLetztenExtra = jetzt - def __bewegeExtra(self): + def __bewegeExtra(self, dt: float): for extra in self.__extraSpriteGruppe: - extra.bewegen() + extra.bewegen(dt) extra.einschraenken(self.__screen.get_width()) def __kollision(self): @@ -215,33 +217,31 @@ class Game(Szene): def getScore(self): return self.__score - def beiUpdate(self): - + def beiUpdate(self, dt: float): + if self.__derSpieler.schuss(): - self.__spielerLaserSpriteGruppe.add(Laser(self.__derSpieler.getLaserPostion(), -10)) + self.__spielerLaserSpriteGruppe.add(Laser(self.__derSpieler.getLaserPostion(), -600.0)) self.__shootSound.play() - self.__derSpieler.bewegen() + self.__derSpieler.bewegen(dt) self.__derSpieler.einschraenken(screenLaenge=self.__screen.get_width()) self.__alienSchuss() - self.__bewegeAliens() + self.__bewegeAliens(dt) for laser in self.__alienLaserSpriteGruppe: - laser.bewegen() + laser.bewegen(dt) for laser in self.__spielerLaserSpriteGruppe: - laser.bewegen() + laser.bewegen(dt) self.__kollision() self.__alienUebrig = len(self.__alienSpriteGruppe) self.__erstelleExtra() - self.__bewegeExtra() + self.__bewegeExtra(dt) if self.__alienUebrig <= 0: self.__erstelleAliens(zeilen=6,spalten=8,startX=50, startY=100,xDistanz=20,yDistanz=20) - - self.__clock.tick(60) def beiZeichne(self): self.__screen.blit(self.__hintergrund, (0,0)) @@ -256,15 +256,14 @@ class Game(Szene): self.__bunkerSpriteGruppe.draw(self.__screen) - self.__dieGUI.zeichneText(f'Score: {self.__score}', 12, 100, self.__screen.get_height()*0.05, (255,255,255)) - self.__dieGUI.zeichneText(f'Leben: {self.__derSpieler.getLeben()}', 12, self.__screen.get_width()-100, self.__screen.get_height()*0.05, (255,255,255)) + self.__dieGUI.zeichneText(f'Score: {self.__score}', 12, 100, int(self.__screen.get_height()*0.05), (255,255,255)) + self.__dieGUI.zeichneText(f'Leben: {self.__derSpieler.getLeben()}', 12, self.__screen.get_width()-100, int(self.__screen.get_height()*0.05), (255,255,255)) pygame.display.flip() class Benennung(Szene): def __init__(self, score: int): super().__init__() self.__screen = pygame.display.set_mode((600,800)) - self.__clock = pygame.time.Clock() self.__hintergrund = pygame.Surface((self.__screen.get_width(), self.__screen.get_height())) self.__hintergrund.fill((0,0,0)) @@ -293,17 +292,15 @@ class Benennung(Szene): # Limitiere Spielername auf 3 Zeichen self.__spielerName += event.unicode - def beiUpdate(self): + def beiUpdate(self, dt: float): pass def beiZeichne(self): self.__screen.blit(self.__hintergrund, (0,0)) - self.__dieGUI.zeichneText(f'Bitte geben sie ihren Name ein!', 12, self.__screen.get_width()/2, self.__screen.get_height()/2-50, (255,255,255)) - self.__dieGUI.zeichneText(f'{self.__spielerName} : {self.__score}', 12, self.__screen.get_width()/2, self.__screen.get_height()/2, (255,255,255)) - - self.__clock.tick(999) + self.__dieGUI.zeichneText(f'Bitte geben sie ihren Name ein!', 12, self.__screen.get_width()//2, self.__screen.get_height()//2-50, (255,255,255)) + self.__dieGUI.zeichneText(f'{self.__spielerName} : {self.__score}', 12, self.__screen.get_width()//2, self.__screen.get_height()//2, (255,255,255)) pygame.display.flip() @@ -314,7 +311,7 @@ class Score(Szene): self.__spielerListe = spielerListe self.__dieGUI = GUI(self.__screen) - self.__zeichneHighScoreListe(self.__screen.get_width()/2, 100, 50) + self.__zeichneHighScoreListe(self.__screen.get_width()//2, 100, 50) pygame.display.flip() @@ -330,9 +327,12 @@ class Score(Szene): else: self.__dieGUI.zeichneText(f'{i+1}. ___ : ___', 12, x, y, (255,255,255)) - self.__dieGUI.zeichneRoundedButton('Retry Press Space', 8, self.__screen.get_width()/2, self.__screen.get_height()-30, 180, 20, 5, (255,255,255), (0,0,0)) + self.__dieGUI.zeichneRoundedButton('Retry Press Space', 8, self.__screen.get_width()//2, self.__screen.get_height()-30, 180, 20, 5, (255,255,255), (0,0,0)) def beiEingabe(self, events: list): for event in events: if event.key == pygame.K_SPACE: - self._wechselSzene = True \ No newline at end of file + self._wechselSzene = True + + def beiUpdate(self, dt: float): + pass \ No newline at end of file diff --git a/__init__.py b/__init__.py index adf7a03..56942e2 100644 --- a/__init__.py +++ b/__init__.py @@ -4,6 +4,5 @@ from Steuerung import Steuerung pygame.init() dieSteuerung = Steuerung() -dieSteuerung.loop() pygame.quit() \ No newline at end of file -- cgit v1.3.1