From 1e4059dc0dd52f40378570880b7a1e40911ad3c7 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Wed, 10 Jun 2026 18:00:11 +0200 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20Boost-=20und=20Dash-Funktionen=20f?= =?UTF-8?q?=C3=BCr=20den=20Spieler=20hinzu;=20verbessere=20die=20Physik-Lo?= =?UTF-8?q?gik=20und=20aktualisiere=20die=20Partikel-Generierung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- editor.py | 2 +- game.py | 32 +++++++++-- scripts/entities.py | 133 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 151 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 463e37b..c389d1a 100644 --- a/.gitignore +++ b/.gitignore @@ -222,4 +222,4 @@ spickzettel.md start.bat Dateien erstellen.txt map.json -testen \ No newline at end of file +testing/ \ No newline at end of file diff --git a/editor.py b/editor.py index 2b563f7..9635d7f 100644 --- a/editor.py +++ b/editor.py @@ -57,7 +57,7 @@ class Editor: # Scroll-Offset fürs Rendern render_scroll: tuple[int, int] = (int(self.scroll[0]), int(self.scroll[1])) - # + self.tilemap.render(surface=self.display, offset=render_scroll) # Aktuelle Kachel (Kopie) diff --git a/game.py b/game.py index e005ac4..b483c06 100644 --- a/game.py +++ b/game.py @@ -55,6 +55,12 @@ class Game: "particles/leaf": Animation( load_images(path="particles/leaf"), image_duration=20, loop=False ), + "particles/boost": Animation( + load_images(path="particles/boost"), image_duration=20, loop=False + ), + "particles/particle": Animation( + load_images(path="particles/particle"), image_duration=6, loop=False + ) } self.player: Player = Player(game=self, pos=(50, 50), size=(8, 15)) @@ -77,6 +83,7 @@ class Game: self.clouds: Clouds = Clouds(cloud_images=self.assets["clouds"], count=16) self.isJumping: bool = False self.scroll: list[float] = [0, 0] + # self.boost: bool = False def run(self) -> None: while self.running: @@ -117,6 +124,7 @@ class Game: self.tilemap, movement=((self.movement[1] - self.movement[0]), 0) ) self.player.render(surface=self.display, offset=render_scroll) + # self.player.boost(self.boost) # print(int(self.player.pos[0])) # print(int(self.player.pos[1])) # print(self.tilemap.tiles_around(self.player.pos)) @@ -140,18 +148,30 @@ class Game: self.movement[0] = True if event.key == pygame.K_d: self.movement[1] = True - if event.key == pygame.K_SPACE: # and not self.isJumping - self.player.velocity[1] -= 3 - self.isJumping = True + if event.key == pygame.K_SPACE or event.key == pygame.K_w: # and not self.isJumping + self.player.jump() + + if event.key == pygame.K_m: + # self.boost = True + self.player.boost() + + if event.key == pygame.K_x: + self.player.dash() + if event.type == pygame.KEYUP: if event.key == pygame.K_a: self.movement[0] = False + if event.key == pygame.K_d: self.movement[1] = False + if event.key == pygame.K_m: + self.boost = False + self.screen.blit( pygame.transform.scale(self.display, self.screen.get_size()), (0, 0) ) + pygame.display.update() self.clock.tick(60) @@ -159,7 +179,7 @@ class Game: sys.exit() + + game = Game() - - -game.run() +game.run() \ No newline at end of file diff --git a/scripts/entities.py b/scripts/entities.py index 5f71cb9..efbd36e 100644 --- a/scripts/entities.py +++ b/scripts/entities.py @@ -1,6 +1,9 @@ import pygame +import math +import random from dataclasses import dataclass from scripts.animation import Animation +from scripts.particle import Particle from scripts.tilemap import Tilemap @@ -13,7 +16,9 @@ class Collisions: class PhysicsEntity: - def __init__(self, game, e_type: str, pos: tuple[float, float], size: tuple[int, int]): + def __init__( + self, game, e_type: str, pos: tuple[float, float], size: tuple[int, int] + ): self.game = game self.e_type: str = e_type self.pos: list[float] = list(pos) @@ -28,11 +33,12 @@ class PhysicsEntity: self.animation_offset: tuple[int, int] = (-3, -3) self.animation: Animation self.set_action("idle") + self.last_movement = [0, 0] def update(self, tilemap: Tilemap, movement: tuple[float, float] = (0, 0)) -> None: self.collisions = Collisions() frame_movement: tuple[float, float] = ( - (movement[0] + self.velocity[0]) * self.speed, + (movement[0] + self.velocity[0]), movement[1] + self.velocity[1], ) self.pos[0] += frame_movement[0] @@ -72,6 +78,7 @@ class PhysicsEntity: self.flip = False if movement[0] < 0: self.flip = True + self.last_movement = movement if self.collisions.bottom or self.collisions.top: self.velocity[1] = 0 @@ -102,7 +109,10 @@ class PhysicsEntity: class Player(PhysicsEntity): def __init__(self, game, pos: tuple[float, float], size: tuple[int, int]): super().__init__(game, "player", pos, size) - self.air_time: int = 0 # Neu! Zählt, wie lange wir fallen/springe + self.air_time: int = 0 # Neu! Zählt, wie lange wir fallen/springen + self.jumps: int = 0 + self.wall_slide: bool = False + self.dashing: int = 0 def update(self, tilemap: Tilemap, movement: tuple[float, float] = (0, 0)) -> None: super().update(tilemap, movement) @@ -111,14 +121,117 @@ class Player(PhysicsEntity): if self.collisions.bottom: self.air_time = 0 + self.jumps = 1 # Wenn wir länger als 4 Frames in der Luft sind -> Springen! - if self.air_time > 4: - self.set_action("jump") + self.wall_slide = False - # Wenn wir nicht in der Luft sind, aber uns bewegen -> Rennen! - elif movement[0] != 0: - self.set_action("run") + if self.collisions.left or self.collisions.right and self.air_time > 4: + self.wall_slide = True + self.velocity[1] = min(self.velocity[1], 0.5) - # Sonst -> Rumstehen! + if self.collisions.left: + self.flip = True + else: + self.flip = False + + self.set_action("wall_slide") + + if not self.wall_slide: + if self.air_time > 4: + self.set_action("jump") + + # Wenn wir nicht in der Luft sind, aber uns bewegen -> Rennen! + elif movement[0] != 0: + self.set_action("run") + + # Sonst -> Rumstehen! + else: + self.set_action("idle") + + if abs(self.dashing) in {60, 50}: + for _ in range(20): + particle_angle = random.random() * math.pi * 2 + particle_speed = random.random() * 0.5 + 0.5 + particle_velocity = [ + math.cos(particle_angle) * particle_speed, + math.sin(particle_angle) * particle_speed, + ] + particle_pos = self.rect().center + particle_startframe = random.randint(0, 7) + self.game.particles.append( + Particle( + self.game, + "particle", + particle_pos, + particle_velocity, + particle_startframe, + ) + ) + + if self.dashing > 0: + self.dashing = max(0, self.dashing - 1) # 60 → 59 → ... → 0 + if self.dashing < 0: + self.dashing = min(0, self.dashing + 1) # -60 → -59 → ... → 0 + + if abs(self.dashing) > 50: + self.velocity[0] = abs(self.dashing) / self.dashing * 8 + + if abs(self.dashing) == 51: + self.velocity[0] *= 0.1 + + particle_velocity = [ + abs(self.dashing) / self.dashing * random.random() * 3, + 0, + ] + + self.game.particles.append(Particle(self.game, "particle", self.rect().center, particle_velocity, random.randint(0, 7))) + + if self.velocity[0] > 0: + self.velocity[0] = max(self.velocity[0] - 0.1, 0) else: - self.set_action("idle") + self.velocity[0] = min(self.velocity[0] + 0.1, 0) + + def jump(self) -> None | bool: + if self.wall_slide: + if self.flip and self.last_movement[0] < 0: + self.velocity[0] = 3.5 + self.velocity[1] = -2.5 + self.air_time = 5 + self.jumps = max(0, self.jumps - 1) + + elif not self.flip and self.last_movement[0] > 0: + self.velocity[0] = -3.5 + self.velocity[1] = -2.5 + self.air_time = 5 + self.jumps = max(0, self.jumps - 1) + + elif self.jumps > 0: + self.velocity[1] = -3 + self.jumps -= 1 + self.air_time = 5 + return True + + def boost(self, boosting: bool = False): + # if boosting: + # self.velocity[1] -= 5 + # boost_particle = Particle(self.game, "boost", (self.pos[0] + self.size[0]//2, self.pos[1] + self.size[1]//2)) + # self.game.particles.append(boost_particle) + self.velocity[1] -= 100000 + boost_particle = Particle( + self.game, + "boost", + (self.pos[0] + self.size[0] // 2, self.pos[1] + self.size[1] // 2), + ) + self.game.particles.append(boost_particle) + + def dash(self) -> None: + if not self.dashing: + if self.flip: + self.dashing = -60 + else: + self.dashing = 60 + + + def render(self, surface, offset=(0, 0)): + if abs(self.dashing) <= 50: + super().render(surface, offset) \ No newline at end of file