import pygame import settings from player import Player from obstacle import Obstacle import random from item import Item class World: def __init__(self, screen, player_name=""): self.start_ticks = pygame.time.get_ticks() self.level_started = False self.level_start_time = None self.time_passed = 0 # Hindernisse self.obstacles = [] while len(self.obstacles) < settings.world.obstacle.amount: x = random.randint(500, 12500) # Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen if all(abs(x - obs.rect.x) > 800 for obs in self.obstacles): self.obstacles.append(Obstacle(x, 500, settings.world.obstacle.box)) # ITEMS self.items = [] while len(self.items) < settings.world.items.amount: x = random.randint(200, 12800) y = random.randint(100, 500) # Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen if all(abs(x - item.rect.x) > 200 for item in self.items): self.items.append(Item(x, y)) # Welt Generierung self.screen = screen self.background = pygame.image.load(settings.BACKGROUND_IMG).convert() self.bg_width = self.background.get_width() # Boden self.ground_rect = pygame.Rect(0, 650, 5000 * 2.7, 80) # Boden full_image = pygame.image.load(settings.world.ground.img).convert_alpha() # --- Ausschneiden des Bereichs cropped = pygame.Surface((settings.world.ground.crop_scale_right, settings.world.ground.crop_height), pygame.SRCALPHA) cropped.blit(full_image, (0, 0), (0, settings.world.ground.crop_top, settings.world.ground.crop_scale_right, settings.world.ground.crop_height)) # --- Skalieren für Anzeige self.ground_image = pygame.transform.scale(cropped, (settings.world.ground.scale_width, settings.world.ground.scale_height)) self.tile_width = self.ground_image.get_width() # ZIEL FLAGGEN goal_flag_image = pygame.image.load(settings.world.goal.img).convert_alpha() self.goal_flag = pygame.transform.scale(goal_flag_image, settings.world.goal.size) # Spieler self.player = Player(200, 500) # Spieler # SCORE self.save_score = 0 # Spielername self.player_name = player_name def draw(self): self.screen.fill((0, 0, 0)) # Bildschirm löschen, bevor gezeichnet wird camera_offset = self.player.rect.centerx - settings.SCREEN_WIDTH // 2 world_width = max(self.bg_width, max([obs.rect.right for obs in self.obstacles] + [self.ground_rect.right])) camera_offset = max(0, min(camera_offset, world_width - settings.SCREEN_WIDTH)) score = self.player.update( ground_y=self.ground_rect.top, obstacles=self.obstacles, items=self.items, score=0, input_allowed=self.level_started ) if score != 0: self.save_score += 10 print(self.save_score) if settings.DEBUG else None bg_offset = int(camera_offset * 0.3) # Parallax: langsamer bewegen self.screen.blit(self.background, (-bg_offset, 0)) # Boden kacheln ohne Parallax start_tile = (camera_offset // self.tile_width) * self.tile_width end_x = camera_offset + settings.SCREEN_WIDTH x = start_tile while x < end_x: screen_x = x - camera_offset self.screen.blit(self.ground_image, (screen_x, self.ground_rect.top)) x += self.tile_width for obs in self.obstacles: obs.draw(self.screen, camera_offset) for items in self.items: items.draw(self.screen, camera_offset) player_screen_x = self.player.rect.x - camera_offset # ZIEL FLAGGEN BACK self.screen.blit(self.goal_flag, (settings.world.goal.position_x - camera_offset, self.ground_rect.top-160)) # PLAYER self.screen.blit(self.player.image, (player_screen_x, self.player.rect.y)) font = pygame.font.Font(settings.fonts.PressStart2P, 24) name_surface = font.render(self.player_name, True, (255, 255, 255)) self.screen.blit(name_surface, (20, 20)) current_ticks = pygame.time.get_ticks() elapsed_seconds = (current_ticks - self.start_ticks) // 1000 if not self.level_started: countdown = max(0, settings.world.countdown - elapsed_seconds) font = pygame.font.Font(settings.fonts.PressStart2P, 72) if countdown > 0: countdown_surface = font.render(str(countdown), True, (255, 255, 255)) else: countdown_surface = font.render("GO!", True, (0, 255, 0)) text_rect = countdown_surface.get_rect(center=(settings.SCREEN_WIDTH // 2, settings.SCREEN_HEIGHT // 2)) self.screen.blit(countdown_surface, text_rect) if countdown == 0: if self.level_start_time is None: self.level_start_time = pygame.time.get_ticks() if elapsed_seconds >= settings.world.countdown: self.level_started = True return # Solange Countdown läuft, alles andere nicht zeichnen else: self.time_passed = (pygame.time.get_ticks() - self.level_start_time) / 1000 # in Sekunden def handle_event(self, event): if not self.level_started: return None # Keine Events verarbeiten, solange Countdown läuft if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: if settings.DEBUG: print("ESC-Pressed") return "menu" return None