⚙️ Physik-Engines
Überblick der Physik-Engines
Arcade bietet drei eingebaute Physik-Engines für unterschiedliche Anforderungen – von einfacher Bewegung bis zu realistischer Simulation.
Figur springt autonom über Plattformen. Gelbe Pfeile = Gravitationsvektor.
| Engine | Komplexität | Anwendung |
|---|---|---|
| PhysicsEngineSimple | ⭐ | Top-Down-Spiele, einfache Bewegung ohne Schwerkraft |
| PhysicsEnginePlatformer | ⭐⭐ | Sidescroller, Jump'n'Run mit Gravitation |
| PymunkPhysicsEngine | ⭐⭐⭐ | Realistische Physik: Reibung, Drehmoment, Gelenke |
Ändere Gravitation und Sprungkraft – sieh den Unterschied sofort!
PhysicsEngineSimple
Die einfachste Engine. Verhindert Kollision mit Wänden, keine Schwerkraft. Ideal für Top-Down-Spiele (Zelda-Stil).
def setup(self):
# Spieler erstellen
self.player = arcade.Sprite(
":resources:images/animated_characters/female_person/femalePerson_idle.png",
scale=0.5
)
self.player.center_x = 400
self.player.center_y = 300
# Wände
self.wall_list = arcade.SpriteList(use_spatial_hash=True)
# Physics Engine initialisieren
self.physics_engine = arcade.PhysicsEngineSimple(
player_sprite=self.player,
walls=self.wall_list
)
def on_update(self, delta_time):
# Engine übernimmt Bewegung und Kollision
self.physics_engine.update()
def on_key_press(self, key, modifiers):
if key == arcade.key.UP:
self.player.change_y = 5
elif key == arcade.key.DOWN:
self.player.change_y = -5
elif key == arcade.key.LEFT:
self.player.change_x = -5
elif key == arcade.key.RIGHT:
self.player.change_x = 5
def on_key_release(self, key, modifiers):
if key in (arcade.key.UP, arcade.key.DOWN):
self.player.change_y = 0
elif key in (arcade.key.LEFT, arcade.key.RIGHT):
self.player.change_x = 0
PhysicsEnginePlatformer
Für klassische Plattformspiele. Unterstützt Schwerkraft, Springen auf Plattformen, Leitern und bewegliche Plattformen.
# Konstanten
GRAVITY = 1.0
PLAYER_JUMP_SPEED = 20
PLAYER_MOVEMENT_SPEED = 5
def setup(self):
self.player = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png", 0.5)
self.player.center_x = 128
self.player.center_y = 128
# Wände / Plattformen
self.wall_list = arcade.SpriteList(use_spatial_hash=True)
for x in range(0, 1250, 64):
wall = arcade.Sprite(":resources:images/tiles/grassMid.png", 0.5)
wall.center_x = x
wall.center_y = 32
self.wall_list.append(wall)
# Leitern (optional)
self.ladder_list = arcade.SpriteList(use_spatial_hash=True)
# Physik-Engine mit Schwerkraft
self.physics_engine = arcade.PhysicsEnginePlatformer(
player_sprite=self.player,
platforms=self.wall_list,
gravity_constant=GRAVITY,
ladders=self.ladder_list
)
def on_key_press(self, key, modifiers):
if key == arcade.key.UP:
if self.physics_engine.can_jump():
self.player.change_y = PLAYER_JUMP_SPEED
elif key == arcade.key.LEFT:
self.player.change_x = -PLAYER_MOVEMENT_SPEED
elif key == arcade.key.RIGHT:
self.player.change_x = PLAYER_MOVEMENT_SPEED
def on_update(self, delta_time):
self.physics_engine.update()
platforms-Parameter ebenfalls unterstützt – einfach bewegliche Sprites zur Plattform-Liste hinzufügen und mit change_x animieren.
PymunkPhysicsEngine
Basiert auf der Pymunk-Bibliothek (Chipmunk2D-Wrapper). Ermöglicht realistische Physik mit Masse, Reibung, Elastizität, Gelenken und mehr.
def setup(self):
# Pymunk Engine mit Gravitation
self.physics_engine = arcade.PymunkPhysicsEngine(
damping=0.4, # Luftwiderstand (0 = keine Dämpfung)
gravity=(0, -1000) # Gravitation in m/s² (x, y)
)
# Spieler als dynamisches Objekt hinzufügen
self.physics_engine.add_sprite(
self.player,
friction=0.6,
mass=2.0,
moment=arcade.PymunkPhysicsEngine.MOMENT_INF, # Verhindert Rotation
collision_type="player"
)
# Wände als statische Objekte
self.physics_engine.add_sprite_list(
self.wall_list,
friction=0.6,
collision_type="wall",
body_type=arcade.PymunkPhysicsEngine.STATIC
)
# Kollisions-Handler registrieren
def player_hits_wall(player_sprite, wall_sprite, arbiter, space, data):
print("Spieler trifft Wand!")
return True
self.physics_engine.add_collision_handler(
"player", "wall", player_hits_wall
)
def on_update(self, delta_time):
# Kraft auf Spieler anwenden (statt change_x direkt)
if self.left_pressed:
self.physics_engine.apply_force(self.player, (-1000, 0))
if self.right_pressed:
self.physics_engine.apply_force(self.player, (1000, 0))
self.physics_engine.step(delta_time)
DYNAMIC
Bewegliche Objekte (Spieler, Kugeln, Kisten). Reagieren auf Kräfte und Kollisionen.
STATIC
Unbewegliche Objekte (Wände, Boden). Nehmen an Kollisionen teil, bewegen sich nicht.
KINEMATIC
Manuell bewegte Objekte (Plattformen). Folgen nicht der Physik, kollidieren aber.
Gravitation & Sprung-Mechanik
# Vollständiges Platformer-Beispiel mit verbessertem Sprung
GRAVITY = 0.8
MAX_FALL_SPEED = -20
JUMP_SPEED = 18
COYOTE_TIME = 0.1 # Sekunden nach Absprung noch springen erlaubt
def on_update(self, delta_time):
self.physics_engine.update()
# Coyote Time tracken
if self.physics_engine.can_jump():
self.coyote_timer = COYOTE_TIME
else:
self.coyote_timer -= delta_time
# Fallgeschwindigkeit begrenzen
if self.player.change_y < MAX_FALL_SPEED:
self.player.change_y = MAX_FALL_SPEED
def jump(self):
# Sprung mit Coyote Time
if self.coyote_timer > 0:
self.player.change_y = JUMP_SPEED
self.coyote_timer = 0
# Variable Sprunghöhe (kurzes Antippen = kleiner Sprung)
def on_key_release(self, key, modifiers):
if key == arcade.key.UP:
if self.player.change_y > 0:
self.player.change_y *= 0.5 # Sprung halbieren