diff --git a/assets/backgrounds/background.png b/assets/backgrounds/background.png new file mode 100644 index 0000000..5edd4e7 Binary files /dev/null and b/assets/backgrounds/background.png differ diff --git a/assets/backgrounds/background_II-I.png b/assets/backgrounds/background_II-I.png new file mode 100644 index 0000000..3d3e07a Binary files /dev/null and b/assets/backgrounds/background_II-I.png differ diff --git a/assets/backgrounds/background_II.png b/assets/backgrounds/background_II.png new file mode 100644 index 0000000..38bafd4 Binary files /dev/null and b/assets/backgrounds/background_II.png differ diff --git a/assets/backgrounds/background_III.png b/assets/backgrounds/background_III.png new file mode 100644 index 0000000..b2c92e6 Binary files /dev/null and b/assets/backgrounds/background_III.png differ diff --git a/assets/images/player/fred.png b/assets/images/player/fred.png index e781f4c..4b744cf 100644 Binary files a/assets/images/player/fred.png and b/assets/images/player/fred.png differ diff --git a/assets/images/player/fred_back.png b/assets/images/player/fred_back.png new file mode 100644 index 0000000..f5d4605 Binary files /dev/null and b/assets/images/player/fred_back.png differ diff --git a/assets/images/player/fred_olli.png b/assets/images/player/fred_olli.png index 921d354..48e684e 100644 Binary files a/assets/images/player/fred_olli.png and b/assets/images/player/fred_olli.png differ diff --git a/assets/images/player/fred_turn.png b/assets/images/player/fred_turn.png new file mode 100644 index 0000000..63c68ab Binary files /dev/null and b/assets/images/player/fred_turn.png differ diff --git a/assets/obstacles/box.png b/assets/obstacles/box.png new file mode 100644 index 0000000..eb6c8fc Binary files /dev/null and b/assets/obstacles/box.png differ diff --git a/assets/obstacles/ramp.png b/assets/obstacles/ramp.png new file mode 100644 index 0000000..e72f183 Binary files /dev/null and b/assets/obstacles/ramp.png differ diff --git a/assets/obstacles/stange.png b/assets/obstacles/stange.png new file mode 100644 index 0000000..e12348f Binary files /dev/null and b/assets/obstacles/stange.png differ diff --git a/assets/world/ground_I.png b/assets/world/ground_I.png new file mode 100644 index 0000000..9015fe1 Binary files /dev/null and b/assets/world/ground_I.png differ diff --git a/assets/world/ground_II.png b/assets/world/ground_II.png new file mode 100644 index 0000000..7c6ef01 Binary files /dev/null and b/assets/world/ground_II.png differ diff --git a/src/main.py b/src/main.py index 16f36a8..bee981c 100644 --- a/src/main.py +++ b/src/main.py @@ -8,7 +8,7 @@ from world import World def main(): pygame.init() screen = pygame.display.set_mode((settings.SCREEN_WIDTH, settings.SCREEN_HEIGHT)) - pygame.display.set_caption("The Last Ollie \n A Fred Story") + pygame.display.set_caption("The Last Ollie - A Fred Story") clock = pygame.time.Clock() menu = Menu(screen) @@ -39,7 +39,7 @@ def main(): if current_scene == "menu": menu.draw() elif current_scene == "world": - world.player.update(world.ground_rect.top) + world.player.update(670) world.draw() pygame.display.flip() diff --git a/src/obstacle.py b/src/obstacle.py new file mode 100644 index 0000000..71ebe3e --- /dev/null +++ b/src/obstacle.py @@ -0,0 +1,14 @@ +import pygame +import settings + +class Obstacle: + def __init__(self, x, y, image_path): + self.image = pygame.image.load(image_path).convert_alpha() + self.image = pygame.transform.scale(self.image, (300, 150)) # Größe anpassen + self.rect = self.image.get_rect(topleft=(x, y)) + + def draw(self, screen, camera_offset): + screen.blit(self.image, (self.rect.x - camera_offset, self.rect.y)) + + def get_rect(self): + return self.rect \ No newline at end of file diff --git a/src/player.py b/src/player.py index 900c6ac..f4e5a6e 100644 --- a/src/player.py +++ b/src/player.py @@ -3,14 +3,16 @@ import settings class Player: def __init__(self, x, y): - self.image_normal = pygame.transform.scale( - pygame.image.load(settings.player.fred.normal).convert_alpha(), - settings.player.size - ) - self.image_jump = pygame.transform.scale( - pygame.image.load(settings.player.fred.olli).convert_alpha(), - settings.player.size - ) + # PLAYER BILDER + # --- NORMAL + self.image_normal = pygame.transform.scale(pygame.image.load(settings.player.fred.normal).convert_alpha(),settings.player.size) + + # --- JUMP + self.image_jump = pygame.transform.scale(pygame.image.load(settings.player.fred.olli).convert_alpha(),settings.player.size) + + # --- BACK + self.image_left = pygame.transform.scale(pygame.image.load(settings.player.fred.left).convert_alpha(),settings.player.size) + self.image = self.image_normal # Anfangszustand self.rect = self.image.get_rect(topleft=(x, y)) self.velocity_y = 0 @@ -19,25 +21,33 @@ class Player: self.jump_strength = settings.player.jump_strength self.on_ground = False - def update(self, ground_y): + def update(self, ground_y, obstacles=[]): keys = pygame.key.get_pressed() - was_on_ground = self.on_ground + + # Bewegung seitlich if keys[pygame.K_LEFT]: self.rect.x -= self.speed if keys[pygame.K_RIGHT]: self.rect.x += self.speed + + # Sprung if keys[pygame.K_SPACE] and self.on_ground: self.velocity_y = self.jump_strength self.on_ground = False - if self.on_ground and self.image != self.image_normal: - self.image = self.image_normal - elif not self.on_ground and self.image != self.image_jump: - self.image = self.image_jump - if not self.on_ground and was_on_ground and settings.DEBUG: - print("Fred springt!") + # Gravitation self.velocity_y += self.gravity self.rect.y += self.velocity_y + self.on_ground = False # zurücksetzen + + # Plattform-Kollision prüfen + for obs in obstacles: + if self.rect.colliderect(obs.get_rect()): + # nur wenn Spieler von oben kommt + if self.velocity_y > 0 and self.rect.bottom <= obs.get_rect().top + 20: + self.rect.bottom = obs.get_rect().top + self.velocity_y = 0 + self.on_ground = True # Boden-Kollision if self.rect.bottom >= ground_y: @@ -45,5 +55,15 @@ class Player: self.velocity_y = 0 self.on_ground = True + # Bildlogik + if not self.on_ground: + self.image = self.image_jump + elif keys[pygame.K_LEFT]: + self.image = self.image_left + elif keys[pygame.K_RIGHT]: + self.image = self.image_normal + else: + self.image = self.image_normal + def draw(self, screen): screen.blit(self.image, self.rect) \ No newline at end of file diff --git a/src/settings.py b/src/settings.py index 75f9330..bf7e61f 100644 --- a/src/settings.py +++ b/src/settings.py @@ -5,20 +5,34 @@ FPS = 60 DEBUG = True Mute = True START_POINT = "world" # world, menu +BACKGROUND_IMG = "../assets/backgrounds/background_III.png" # Schriftarten class fonts: PressStart2P = '../assets/fonts/PressStart2P-Regular.ttf' class player: - size = (100, 100) - speed = 5 - gravity = 1 - jump_strength = -18 + size = (110, 200) + speed = 12 if DEBUG else 5 + gravity = 0.8 + jump_strength = -20 class fred: normal = "../assets/images/player/fred.png" olli = "../assets/images/player/fred_olli.png" + left = "../assets/images/player/fred_back.png" + +class world: + class ground: + img = "../assets/world/ground_II.png" + crop_top = 500 + crop_height = 300 + scale_height = 80 + scale_width = 300 + crop_scale_right = 1400 + + class obstacle: + box = "../assets/obstacles/box.png" # Farben class MyColors: diff --git a/src/world.py b/src/world.py index 8b07b91..df1c3ee 100644 --- a/src/world.py +++ b/src/world.py @@ -1,18 +1,59 @@ import pygame import settings from player import Player +from obstacle import Obstacle +import random class World: def __init__(self, screen): + # Hindernisse + self.obstacles = [] + obstacle_count = random.randint(2, 3) + for _ in range(obstacle_count): + x = random.randint(500, 4000) # X-Position irgendwo in der Welt + self.obstacles.append(Obstacle(x, 520, settings.world.obstacle.box)) + + # Welt Generierung self.screen = screen - self.background_color = (135, 206, 235) # Himmelblau - self.ground_rect = pygame.Rect(0, 600, 1280, 120) # Boden + 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() + + # Spieler self.player = Player(200, 500) # Spieler def draw(self): - self.screen.fill(self.background_color) - pygame.draw.rect(self.screen, (124, 252, 0), self.ground_rect) # Grün für Boden - self.player.draw(self.screen) + 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)) + self.player.update(self.ground_rect.top, self.obstacles) + + 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) + + player_screen_x = self.player.rect.x - camera_offset + self.screen.blit(self.player.image, (player_screen_x, self.player.rect.y)) def handle_event(self, event): if event.type == pygame.KEYDOWN: