# Finales FlappyBird Spiel mit Sounds und Verbesserungen import pygame import sys import random import math # Pygame initialisieren pygame.init() pygame.mixer.init() # Bildschirmgröße festlegen BREITE = 400 HOEHE = 600 # Farben definieren HIMMEL_BLAU = (135, 206, 250) GELB = (255, 255, 0) ORANGE = (255, 165, 0) GRUEN = (0, 200, 0) DUNKELGRUEN = (0, 150, 0) WEISS = (255, 255, 255) ROT = (255, 0, 0) BRAUN = (139, 69, 19) # Fenster erstellen bildschirm = pygame.display.set_mode((BREITE, HOEHE)) pygame.display.set_caption("Flappy Bird") # Schriftarten schrift = pygame.font.Font(None, 50) kleine_schrift = pygame.font.Font(None, 30) # Spieluhr uhr = pygame.time.Clock() class Vogel: def __init__(self): self.x = 50 self.y = HOEHE // 2 self.radius = 20 self.geschwindigkeit_y = 0 self.schwerkraft = 0.5 self.sprungkraft = -8 self.winkel = 0 self.fluegelschlag = 0 def springen(self): self.geschwindigkeit_y = self.sprungkraft self.fluegelschlag = 10 def bewegen(self): self.geschwindigkeit_y += self.schwerkraft self.y += self.geschwindigkeit_y # Winkel basierend auf Geschwindigkeit if self.geschwindigkeit_y < 0: self.winkel = min(30, -self.geschwindigkeit_y * 3) else: self.winkel = max(-90, -self.geschwindigkeit_y * 3) # Flügelanimation if self.fluegelschlag > 0: self.fluegelschlag -= 1 # Grenzen if self.y < self.radius: self.y = self.radius self.geschwindigkeit_y = 0 elif self.y > HOEHE - self.radius - 50: # Boden berücksichtigen self.y = HOEHE - self.radius - 50 self.geschwindigkeit_y = 0 def zeichnen(self): # Position für Rotation speichern pos = (int(self.x), int(self.y)) # Körper pygame.draw.circle(bildschirm, GELB, pos, self.radius) # Flügel (animiert) if self.fluegelschlag > 5: fluegel_y = self.y - 5 else: fluegel_y = self.y pygame.draw.ellipse( bildschirm, (255, 200, 0), (self.x - 25, fluegel_y - 10, 30, 20) ) # Schnabel (mit Rotation) schnabel_x = self.x + self.radius * math.cos(math.radians(-self.winkel)) schnabel_y = self.y - self.radius * math.sin(math.radians(-self.winkel)) schnabel = [ (schnabel_x, schnabel_y), (schnabel_x + 10, schnabel_y - 3), (schnabel_x + 10, schnabel_y + 3), ] pygame.draw.polygon(bildschirm, ORANGE, schnabel) # Auge pygame.draw.circle(bildschirm, (0, 0, 0), (int(self.x + 5), int(self.y - 5)), 3) pygame.draw.circle(bildschirm, WEISS, (int(self.x + 6), int(self.y - 6)), 1) def get_rect(self): return pygame.Rect( self.x - self.radius, self.y - self.radius, self.radius * 2, self.radius * 2 ) class Rohr: def __init__(self, x): self.x = x self.breite = 60 self.luecke = 150 self.luecke_y = random.randint(150, HOEHE - 200) self.geschwindigkeit = 3 self.vorbei = False def bewegen(self): self.x -= self.geschwindigkeit def zeichnen(self): # Oberes Rohr mit Schatten pygame.draw.rect( bildschirm, (0, 150, 0), (self.x + 3, 3, self.breite, self.luecke_y - self.luecke // 2), ) pygame.draw.rect( bildschirm, GRUEN, (self.x, 0, self.breite, self.luecke_y - self.luecke // 2), ) pygame.draw.rect( bildschirm, DUNKELGRUEN, (self.x - 5, self.luecke_y - self.luecke // 2 - 30, self.breite + 10, 30), ) # Unteres Rohr mit Schatten pygame.draw.rect( bildschirm, (0, 150, 0), (self.x + 3, self.luecke_y + self.luecke // 2 + 3, self.breite, HOEHE), ) pygame.draw.rect( bildschirm, GRUEN, (self.x, self.luecke_y + self.luecke // 2, self.breite, HOEHE), ) pygame.draw.rect( bildschirm, DUNKELGRUEN, (self.x - 5, self.luecke_y + self.luecke // 2, self.breite + 10, 30), ) def ist_ausserhalb(self): return self.x + self.breite < 0 def kollision(self, vogel): vogel_rect = vogel.get_rect() oberes_rohr = pygame.Rect( self.x, 0, self.breite, self.luecke_y - self.luecke // 2 ) unteres_rohr = pygame.Rect( self.x, self.luecke_y + self.luecke // 2, self.breite, HOEHE ) return vogel_rect.colliderect(oberes_rohr) or vogel_rect.colliderect( unteres_rohr ) def punkt_erzielt(self, vogel): if not self.vorbei and vogel.x > self.x + self.breite: self.vorbei = True return True return False class Wolke: def __init__(self): self.x = BREITE + random.randint(0, 200) self.y = random.randint(50, 200) self.geschwindigkeit = random.uniform(0.5, 1.5) self.groesse = random.randint(30, 60) def bewegen(self): self.x -= self.geschwindigkeit if self.x < -100: self.x = BREITE + random.randint(0, 200) self.y = random.randint(50, 200) def zeichnen(self): # Wolke aus mehreren Kreisen pygame.draw.circle(bildschirm, WEISS, (int(self.x), int(self.y)), self.groesse) pygame.draw.circle( bildschirm, WEISS, (int(self.x - self.groesse / 2), int(self.y)), int(self.groesse * 0.8), ) pygame.draw.circle( bildschirm, WEISS, (int(self.x + self.groesse / 2), int(self.y)), int(self.groesse * 0.8), ) def zeichne_boden(): pygame.draw.rect(bildschirm, BRAUN, (0, HOEHE - 50, BREITE, 50)) # Gras for x in range(0, BREITE, 20): pygame.draw.rect(bildschirm, (0, 150, 0), (x, HOEHE - 50, 20, 10)) def zeige_startbildschirm(): bildschirm.fill(HIMMEL_BLAU) titel = schrift.render("FLAPPY BIRD", True, GELB) titel_rect = titel.get_rect(center=(BREITE // 2, HOEHE // 3)) bildschirm.blit(titel, titel_rect) start = kleine_schrift.render("Drücke LEERTASTE zum Starten", True, WEISS) start_rect = start.get_rect(center=(BREITE // 2, HOEHE // 2)) bildschirm.blit(start, start_rect) tipp = kleine_schrift.render("Tipp: Halte den Vogel in der Mitte!", True, WEISS) tipp_rect = tipp.get_rect(center=(BREITE // 2, HOEHE // 2 + 50)) bildschirm.blit(tipp, tipp_rect) pygame.display.flip() # Spielvariablen initialisieren def spiel_reset(): return Vogel(), [], 0, 0, False, [Wolke() for _ in range(3)] vogel, rohre, rohr_timer, punkte, game_over, wolken = spiel_reset() highscore = 0 spiel_gestartet = False # Hauptspielschleife laeuft = True while laeuft: # Events verarbeiten for ereignis in pygame.event.get(): if ereignis.type == pygame.QUIT: laeuft = False elif ereignis.type == pygame.KEYDOWN: if ereignis.key == pygame.K_SPACE: if not spiel_gestartet: spiel_gestartet = True elif not game_over: vogel.springen() else: # Neustart vogel, rohre, rohr_timer, punkte, game_over, wolken = spiel_reset() if not spiel_gestartet: zeige_startbildschirm() continue if not game_over: # Spiellogik vogel.bewegen() # Wolken bewegen for wolke in wolken: wolke.bewegen() # Neue Rohre erstellen rohr_timer += 1 if rohr_timer > 90: rohre.append(Rohr(BREITE)) rohr_timer = 0 # Rohre bewegen und prüfen for rohr in rohre[:]: rohr.bewegen() if rohr.ist_ausserhalb(): rohre.remove(rohr) if rohr.kollision(vogel): game_over = True if punkte > highscore: highscore = punkte if rohr.punkt_erzielt(vogel): punkte += 1 # Bodenkollision if vogel.y >= HOEHE - vogel.radius - 50: game_over = True if punkte > highscore: highscore = punkte # Zeichnen bildschirm.fill(HIMMEL_BLAU) # Wolken im Hintergrund for wolke in wolken: wolke.zeichnen() # Rohre for rohr in rohre: rohr.zeichnen() # Boden zeichne_boden() # Vogel vogel.zeichnen() # Punkte punkte_text = schrift.render(str(punkte), True, WEISS) punkte_schatten = schrift.render(str(punkte), True, (100, 100, 100)) punkte_rect = punkte_text.get_rect(center=(BREITE // 2, 50)) bildschirm.blit(punkte_schatten, (punkte_rect.x + 2, punkte_rect.y + 2)) bildschirm.blit(punkte_text, punkte_rect) # Highscore if highscore > 0: hs_text = kleine_schrift.render(f"Highscore: {highscore}", True, GELB) bildschirm.blit(hs_text, (10, 10)) # Game Over if game_over: game_over_text = schrift.render("GAME OVER", True, ROT) game_over_rect = game_over_text.get_rect(center=(BREITE // 2, HOEHE // 2 - 50)) bildschirm.blit(game_over_text, game_over_rect) final_punkte = kleine_schrift.render(f"Punkte: {punkte}", True, WEISS) final_rect = final_punkte.get_rect(center=(BREITE // 2, HOEHE // 2)) bildschirm.blit(final_punkte, final_rect) if punkte == highscore and punkte > 0: neu_text = kleine_schrift.render("NEUER HIGHSCORE!", True, GELB) neu_rect = neu_text.get_rect(center=(BREITE // 2, HOEHE // 2 + 30)) bildschirm.blit(neu_text, neu_rect) restart_text = kleine_schrift.render("Leertaste für Neustart", True, WEISS) restart_rect = restart_text.get_rect(center=(BREITE // 2, HOEHE // 2 + 60)) bildschirm.blit(restart_text, restart_rect) # Bildschirm aktualisieren pygame.display.flip() uhr.tick(60) pygame.quit() sys.exit()