Physik-Sandbox
Interaktive 2D-Physiksimulation in Python. Über eine Werkzeugleiste erzeugst du Kreise und Rechtecke unterschiedlicher Größe, greifst sie mit der Maus, ziehst sie herum und wirfst sie gegeneinander. Die Körper fallen, prallen ab, reiben, rollen, stapeln sich und kommen stabil zur Ruhe.
Die gesamte Physik ist selbst geschrieben – Vektormathematik, Integration,
Kollisionserkennung und impulsbasierte Kollisionsauflösung verwenden ausschließlich das
Standardmodul math. pygame-ce dient nur für Fenster, Zeichnen,
Eingaben und Zeitmessung.
Funktionen
- Kreise und achsenparallele Rechtecke; Größe, Seitenverhältnis, Elastizität, Dichte und Farbe in der Sidebar einstellbar – die Masse ergibt sich aus Fläche × Dichte.
- Objekte per Klick in die Welt oder per Ziehen aus der Vorschau-Kachel erzeugen.
- Drag & Drop mit Kollisionen: Ein gezogenes Objekt schiebt andere weg und wird von Wänden gestoppt. Beim Loslassen erhält es die geglättete Mausgeschwindigkeit (Werfen).
- Schwerkraft, Kreis–Kreis-, Kreis–Rechteck-, Rechteck–Rechteck- und Wandkollisionen, Restitution, Coulomb-Reibung, Rollen und Rollwiderstand.
- Fester Zeitschritt (120 Hz), semi-impliziter Euler, Warm-Starting, Positionskorrektur, Schlafmodus für ruhende Körper, Geschwindigkeitsgrenze gegen Tunneln.
- Pause, Schwerkraft an/aus, Alles löschen, Debug-Ansicht mit Kontaktpunkten.
Voraussetzungen
- Python 3.10 oder neuer (entwickelt und getestet mit Python 3.14)
- Windows, macOS oder Linux
Warum pygame-ce? Das Original-
pygame(2.6.1) bietet keine fertigen Pakete für Python 3.14.pygame-ceist der API-kompatible Community-Fork; im Code heißt es weiterhinimport pygame.
Einrichtung
Im Projektordner eine virtuelle Umgebung anlegen und die Abhängigkeiten installieren:
python -m venv .venv
Aktivieren – unter Windows (PowerShell):
.venv\Scripts\Activate.ps1
Meldet PowerShell "Die Ausführung von Skripts ist auf diesem System deaktiviert", erlaube lokale Skripte einmalig für deinen Benutzer (danach die Aktivierung wiederholen):
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
Alternativ ohne Aktivierung: Ersetze in allen folgenden Befehlen
| Befehl | durch |
|---|---|
python |
.venv\Scripts\python.exe |
pip |
.venv\Scripts\python.exe -m pip |
pytest |
.venv\Scripts\python.exe -m pytest |
ruff |
.venv\Scripts\ruff.exe |
physics-sandbox |
.venv\Scripts\physics-sandbox.exe |
Unter macOS/Linux:
source .venv/bin/activate
Dann installieren:
pip install -r requirements.txt
requirements.txt installiert pygame-ce und das Projekt selbst im Editable-Modus
(-e .). Den Befehl deshalb im Projektordner ausführen.
Starten
python -m sandbox
Weitere Möglichkeiten:
| Befehl | Wirkung |
|---|---|
python -m sandbox --demo |
startet mit einer Beispielszene (Turm, Kreispyramide, Gummibälle) |
physics-sandbox |
gleichwertiger Befehl, den die Installation anlegt |
python -m sandbox --demo --screenshot bild.png --seconds 3 |
läuft 3 s, speichert ein Bildschirmfoto und beendet sich |
Bedienung (Kurzfassung)
| Eingabe | Aktion |
|---|---|
| Linksklick ins Leere | Objekt erzeugen (gedrückt halten und ziehen = sofort werfen) |
| Linksklick auf Objekt + Ziehen | greifen und verschieben; Loslassen in Bewegung wirft es |
| Ziehen aus der Vorschau-Kachel | neues Objekt aus der Sidebar in die Welt ziehen |
Rechtsklick / Entf |
Objekt unter der Maus löschen |
| Mausrad | Größe ändern (über einem Regler: diesen Regler verstellen) |
Leertaste · G · C |
Pause/Weiter · Schwerkraft an/aus · Alles löschen |
1 · 2 |
Kreis · Rechteck |
F1 · Esc |
Debug-Ansicht · Beenden |
Alle Details: docs/CONTROLS.md.
Entwicklung
Entwicklungswerkzeuge (pytest, pytest-cov, ruff) installieren:
pip install -r requirements-dev.txt
Tests ausführen (inklusive Headless-UI-Tests – es öffnet sich kein Fenster):
pytest
Mit Testabdeckung:
pytest --cov=sandbox --cov-report=term-missing
Code prüfen und formatieren:
ruff check src tests
ruff format src tests
Details zu den Tests: docs/TESTING.md.
Projektstruktur
├── src/sandbox/
│ ├── main.py Einstiegspunkt, App und Game-Loop
│ ├── config.py alle Konstanten (Physik, Interaktion, Farben, Layout)
│ ├── physics/ eigene Physik-Engine – nur `math`, kein pygame
│ │ ├── vector.py Vector2
│ │ ├── shapes.py Circle, Box (AABB), HalfPlane (Wände)
│ │ ├── body.py Body, Material
│ │ ├── collision.py Kollisionserkennung (Narrowphase)
│ │ ├── broadphase.py Sweep-and-Prune
│ │ ├── solver.py Impulsauflösung, Reibung, Rollwiderstand, Positionskorrektur
│ │ ├── sleep.py Schlafmodus (Kontakt-Inseln)
│ │ ├── timestep.py fester Zeitschritt
│ │ └── world.py Welt und Simulationsschritt
│ ├── interaction/ Werkzeuge ohne pygame: Erzeugen, Ziehen, Werfen
│ ├── ui/ Sidebar und selbst gezeichnete Widgets
│ ├── input_handler.py Maus und Tastatur → Aktionen
│ ├── renderer.py Zeichnen der Welt
│ ├── viewport.py Bildschirm ↔ Welt
│ └── demo.py Beispielszene
├── tests/ pytest-Suite (Physik, Interaktion, Headless-UI, Smoke-Test)
├── docs/ Dokumentation
├── requirements.txt Laufzeit-Abhängigkeiten
├── requirements-dev.txt Test- und Linting-Werkzeuge
└── pyproject.toml Paket-, ruff- und pytest-Konfiguration
Dokumentation
- docs/PHYSIK_EINSTIEG.md – die Physik Schritt für Schritt für Einsteiger
- docs/PHYSICS.md – die verwendete Physik und ihre Formeln
- docs/ARCHITECTURE.md – Module, Datenfluss im Game-Loop, Diagramme
- docs/TESTING.md – Tests ausführen, was getestet wird, Headless-Modus
- docs/CONTROLS.md – alle Maus- und Tastaturbefehle
Screenshots
Demo-Szene mit gerade geworfenem Rechteck (gelb umrandet, der Pfeil zeigt die Wurfgeschwindigkeit):
Debug-Ansicht (F1): Kontaktpunkte (gelb), Kontaktnormalen (rot) und Kennzahlen:
Ein aktuelles Bild der Demo-Szene erzeugst du jederzeit mit
python -m sandbox --demo --screenshot docs/images/demo.png.

