194 lines
6.8 KiB
Markdown
194 lines
6.8 KiB
Markdown
# 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](https://pyga.me/) 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-ce` ist der API-kompatible Community-Fork; im Code heißt es weiterhin
|
||
> `import pygame`.
|
||
|
||
## Einrichtung
|
||
|
||
Im Projektordner eine virtuelle Umgebung anlegen und die Abhängigkeiten installieren:
|
||
|
||
```bash
|
||
python -m venv .venv
|
||
```
|
||
|
||
Aktivieren – unter Windows (PowerShell):
|
||
|
||
```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):
|
||
|
||
```powershell
|
||
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:
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
```
|
||
|
||
Dann installieren:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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](docs/CONTROLS.md).
|
||
|
||
## Entwicklung
|
||
|
||
Entwicklungswerkzeuge (pytest, pytest-cov, ruff) installieren:
|
||
|
||
```bash
|
||
pip install -r requirements-dev.txt
|
||
```
|
||
|
||
Tests ausführen (inklusive Headless-UI-Tests – es öffnet sich kein Fenster):
|
||
|
||
```bash
|
||
pytest
|
||
```
|
||
|
||
Mit Testabdeckung:
|
||
|
||
```bash
|
||
pytest --cov=sandbox --cov-report=term-missing
|
||
```
|
||
|
||
Code prüfen und formatieren:
|
||
|
||
```bash
|
||
ruff check src tests
|
||
```
|
||
|
||
```bash
|
||
ruff format src tests
|
||
```
|
||
|
||
Details zu den Tests: [docs/TESTING.md](docs/TESTING.md).
|
||
|
||
## Projektstruktur
|
||
|
||
```text
|
||
├── 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](docs/PHYSIK_EINSTIEG.md) – die Physik Schritt für Schritt für Einsteiger
|
||
- [docs/PHYSICS.md](docs/PHYSICS.md) – die verwendete Physik und ihre Formeln
|
||
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) – Module, Datenfluss im Game-Loop, Diagramme
|
||
- [docs/TESTING.md](docs/TESTING.md) – Tests ausführen, was getestet wird, Headless-Modus
|
||
- [docs/CONTROLS.md](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`.
|