diff --git a/assets/images/controller/dreieck.png b/assets/images/controller/dreieck.png new file mode 100644 index 0000000..fb44ce1 Binary files /dev/null and b/assets/images/controller/dreieck.png differ diff --git a/assets/images/controller/kreis.png b/assets/images/controller/kreis.png new file mode 100644 index 0000000..5474cea Binary files /dev/null and b/assets/images/controller/kreis.png differ diff --git a/assets/images/controller/kreuz.png b/assets/images/controller/kreuz.png new file mode 100644 index 0000000..15242cc Binary files /dev/null and b/assets/images/controller/kreuz.png differ diff --git a/assets/images/controller/ps4-control.png b/assets/images/controller/ps4-control.png new file mode 100644 index 0000000..9c52899 Binary files /dev/null and b/assets/images/controller/ps4-control.png differ diff --git a/assets/images/controller/viereck.png b/assets/images/controller/viereck.png new file mode 100644 index 0000000..fcf7200 Binary files /dev/null and b/assets/images/controller/viereck.png differ diff --git a/src/level_complete_screen.py b/src/level_complete_screen.py index c8164f7..540ddfb 100644 --- a/src/level_complete_screen.py +++ b/src/level_complete_screen.py @@ -3,16 +3,22 @@ import settings from settings import MyColors class Endscreen: - def __init__(self, screen, score): + def __init__(self, screen, score, time_passed=0): self.screen = screen self.score = score + self.background = pygame.image.load(settings.BACKGROUND_IMG_COMP).convert_alpha() + self.icon_controller_retry = pygame.image.load(settings.icons.controller.viereck).convert_alpha() + self.icon_controller_menu = pygame.image.load(settings.icons.controller.dreieck).convert_alpha() + self.font = pygame.font.Font(settings.fonts.PressStart2P, 60) self.small_font = pygame.font.Font(settings.fonts.PressStart2P, 24) self.retry_button = pygame.Rect(390, 400, 200, 50) self.menu_button = pygame.Rect(690, 400, 200, 50) + self.time_passed = time_passed + def draw(self): self.screen.blit(self.background, (0, 0)) @@ -20,33 +26,39 @@ class Endscreen: score_text = self.font.render(f"Dein Score: {self.score}", True, (255, 255, 255)) # z.B. Gold self.screen.blit(score_text, (settings.SCREEN_WIDTH // 2 - score_text.get_width() // 2, 200)) + time_text = self.small_font.render(f"Deine Zeit: {self.time_passed:.2f} Sekunden", True, (255, 255, 255)) + self.screen.blit(time_text, (settings.SCREEN_WIDTH // 2 - time_text.get_width() // 2, 300)) + + pygame.draw.rect(self.screen, MyColors.yellow, self.retry_button) pygame.draw.rect(self.screen, MyColors.yellow, self.menu_button) nochmal_text = self.small_font.render("Nochmal", True, MyColors.brown) menu_text = self.small_font.render("Menü", True, MyColors.brown) - self.screen.blit(nochmal_text, (self.retry_button.x + 20, self.retry_button.y + 10)) - self.screen.blit(menu_text, (self.menu_button.x + 35, self.menu_button.y + 10)) + self.screen.blit(nochmal_text, (self.retry_button.x + 15, self.retry_button.y + 10)) + self.screen.blit(menu_text, (self.menu_button.x + 50, self.menu_button.y + 10)) + + self.screen.blit(self.icon_controller_retry, (self.retry_button.bottomleft - 30, )) return self.retry_button, self.menu_button + def handle_event(self, event): - - joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())] - - # Controller-Eingaben prüfen - retry_controller_action = False - menu_controller_action = False - for joystick in joysticks: - if joystick.get_button(2): - retry_controller_action = True - if joystick.get_button(3): - menu_controller_action = True - if event.type == pygame.MOUSEBUTTONDOWN: + print("MOUSEBUTTONDOWN") if settings.DEBUG else None if self.retry_button.collidepoint(event.pos): return "retry" elif self.menu_button.collidepoint(event.pos): return "menu" + if event.type == pygame.MOUSEBUTTONUP: + if self.retry_button.collidepoint(event.pos): + return "retry" + elif self.menu_button.collidepoint(event.pos): + return "menu" + if event.type == pygame.JOYBUTTONDOWN: + if event.button == 3: + return "menu" + elif event.button == 2: + return "retry" return None \ No newline at end of file diff --git a/src/main.py b/src/main.py index 5e9348a..d5efda9 100644 --- a/src/main.py +++ b/src/main.py @@ -20,8 +20,8 @@ def main(): clock = pygame.time.Clock() menu = Menu(screen) - world = World(screen) - endscreen = Endscreen(screen, 000) if settings.DEBUG else endscreen = Endscreen(screen, world.save_score) + world = World(screen, menu.player_name) + endscreen = Endscreen(screen, 000) if settings.DEBUG_ENDSCREEN else Endscreen(screen, world.save_score) current_scene = settings.START_POINT @@ -35,6 +35,7 @@ def main(): menu.handle_event(event) if menu.ready_to_start_game: menu.ready_to_start_game = False # Reset! + world = World(screen, menu.player_name) current_scene = "world" if current_scene == "world": @@ -48,17 +49,22 @@ def main(): if current_scene == "endscreen": action = endscreen.handle_event(event) if action == "retry": + world = World(screen, menu.player_name) current_scene = "world" elif action == "menu": current_scene = "menu" + menu.input_active = False + menu.show_main_buttons = True + menu.ready_to_start_game = False + menu.player_name = "" if current_scene == "menu": menu.draw() elif current_scene == "world": if not world.player.game_paused: - world.player.update(670) world.draw() else: + endscreen = Endscreen(screen, world.save_score, world.time_passed) current_scene = "endscreen" if settings.DEBUG and not hasattr(world, 'level_end_printed'): print("Level beendet!") diff --git a/src/menu.py b/src/menu.py index 11c444d..93bba04 100644 --- a/src/menu.py +++ b/src/menu.py @@ -70,8 +70,8 @@ class Menu: if self.start_button.collidepoint(event.pos): self.input_active = True self.show_main_buttons = False - if self.highscore_button.collidepoint(event.pos) and settings.DEBUG: - print("Highscores anzeigen (später!)") + if settings.DEBUG: + print("Highscores anzeigen (später!)") if self.input_active: if self.back_button.collidepoint(event.pos): self.input_active = False diff --git a/src/player.py b/src/player.py index 2a0456c..0a58cd9 100644 --- a/src/player.py +++ b/src/player.py @@ -16,29 +16,16 @@ class Player: self.image = self.image_normal # Anfangszustand self.rect = self.image.get_rect(topleft=(x, y)) self.velocity_y = 0 - self.speed = settings.player.speed self.gravity = settings.player.gravity self.jump_strength = settings.player.jump_strength self.on_ground = False self.game_paused = False - def update(self, ground_y, obstacles=[], items=[], score=0): + def update(self, ground_y=80, obstacles=[], items=[], score=0, input_allowed=False): keys = pygame.key.get_pressed() joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())] - for i, key in enumerate(keys): - if key: - print(f"Tastatur: Taste {pygame.key.name(i)} gedrückt") if settings.DEBUG_KEY_INPUT else None - - for joystick in joysticks: - for button in range(joystick.get_numbuttons()): - if joystick.get_button(button): - print(f"Controller: Button {button} gedrückt") if settings.DEBUG_KEY_INPUT else None - for axis in range(joystick.get_numaxes()): - if abs(joystick.get_axis(axis)) > 0.5: - print(f"Controller: Stick {axis} bewegt ({joystick.get_axis(axis):.2f})") if settings.DEBUG_KEY_INPUT else None - move_left = keys[pygame.K_LEFT] move_right = keys[pygame.K_RIGHT] jump = keys[pygame.K_SPACE] @@ -53,18 +40,18 @@ class Player: jump = True # Bewegung seitlich - if move_left: - self.rect.x -= self.speed - if move_right: - self.rect.x += self.speed + if move_left and input_allowed: + self.rect.x -= settings.player.speed + if move_right and input_allowed: + self.rect.x += settings.player.speed # Springen - if jump and self.on_ground: + if jump and self.on_ground and input_allowed: self.velocity_y = self.jump_strength self.on_ground = False # Gravitation - self.velocity_y += self.gravity + self.velocity_y += settings.player.gravity self.rect.y += self.velocity_y self.on_ground = False # zurücksetzen diff --git a/src/settings.py b/src/settings.py index e49aa0a..9d7e48a 100644 --- a/src/settings.py +++ b/src/settings.py @@ -6,6 +6,7 @@ SCREEN_HEIGHT = 720 FPS = 60 DEBUG = True DEBUG_KEY_INPUT = False +DEBUG_ENDSCREEN = False Mute = True START_POINT = "endscreen" # world, menu BACKGROUND_IMG = "../assets/backgrounds/background_III.png" @@ -17,9 +18,9 @@ class fonts: class player: size = (110, 200) - speed = 12 if DEBUG else 7 - gravity = 0.8 - jump_strength = -20 + speed = 25 if DEBUG else 18 + gravity = 1.5 + jump_strength = -30 class fred: normal = "../assets/images/player/fred.png" @@ -27,6 +28,7 @@ class player: left = "../assets/images/player/fred_back.png" class world: + countdown = 3 #sekunden class ground: img = "../assets/world/ground_II.png" crop_top = 500 @@ -51,6 +53,12 @@ class world: position_x = 13130 +class icons: + class controller: + kreis = "../assets/images/controller/kreis.png" + viereck = "../assets/images/controller/viereck.png" + dreieck = "../assets/images/controller/dreieck.png" + kreuz = "../assets/images/controller/kreuz.png" diff --git a/src/world.py b/src/world.py index d4fccdb..5e7c179 100644 --- a/src/world.py +++ b/src/world.py @@ -6,7 +6,13 @@ import random from item import Item class World: - def __init__(self, screen): + 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 = [] @@ -52,13 +58,24 @@ class World: # 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(self.ground_rect.top, self.obstacles, self.items) - # print(score) + 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 @@ -88,12 +105,41 @@ class World: # 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" - # self.player.handle_event(event) return None \ No newline at end of file