The game tab held a "Press Play" hint where the picture belongs. It now previews the scene through the active camera, and says "No active camera" when none is switched on. Camera choice and its world position moved into activeCamera.ts so both are testable without Pixi. Entity.x/.y are parent-relative; the viewport used them as the camera's spot, which framed a parented camera at the wrong place.
74 lines
3.7 KiB
Markdown
74 lines
3.7 KiB
Markdown
In der Game View soll anstelle von "Press Play to run the scene here":
|
||
- das aktuelle frame von der kamera dargestellt werden
|
||
- gibt es keine aktive kamera, der text "No active camera"
|
||
|
||
---
|
||
|
||
**Umgesetzt (2026-09-09).** Der Game-Tab zeigt jetzt auch ohne Play das Bild der aktiven Kamera,
|
||
und *"No active camera"*, wenn keine an ist. Der alte Hinweis *"Press ▶ Play to run the scene
|
||
here"* entfaellt ersatzlos — er stand genau da, wo jetzt das Bild ist.
|
||
|
||
Der Tab hat damit zwei Quellen fuer dieselbe Darstellung:
|
||
|
||
| | |
|
||
|---|---|
|
||
| **waehrend Play** | die laufende Welt, wie bisher |
|
||
| **sonst** | das Modell der aktiven Szene, als stehendes Bild |
|
||
|
||
Beide werden durch **dieselbe** Kamera gerahmt (`activeCamera.ts`, siehe unten) und durch
|
||
dieselbe Zeichenroutine gezeichnet. Editor-Symbole (Kamera, Collider, Behavior, Container-Icon)
|
||
fallen in der Vorschau genauso weg wie beim Spielen — die Vorschau zeigt das Spiel, nicht den
|
||
Editor.
|
||
|
||
## Zwei reine Funktionen statt einer Regel an zwei Stellen
|
||
|
||
`src/viewport/activeCamera.ts` beantwortet **welche Kamera und wo**, fuer beide Quellen:
|
||
|
||
- `cameraOfItems(items)` — die Modell-Kamera. `collectHolderItems` liefert bereits
|
||
Hierarchie-Reihenfolge mit aufgeloester Schalterkette, also ist "die erste eingeschaltete"
|
||
hier schlicht der erste Treffer. Damit ist es **dieselbe Regel** wie `World.activeCamera`,
|
||
nicht eine zweite Formulierung davon.
|
||
- `cameraOfWorld(world)` — die laufende Kamera, **an ihrer Weltposition**.
|
||
|
||
## Ein Fehler, den erst die Vorschau sichtbar gemacht hat
|
||
|
||
Der zweite Punkt ist kein Detail: `x`/`y` einer Entity sind **relativ zum Elternteil**. Der
|
||
Game-View hat sie bisher direkt als Kamerastandort benutzt. Eine Kamera, die unter einem Objekt
|
||
haengt (der uebliche Weg, sie einem Spieler folgen zu lassen), wurde deshalb an der falschen
|
||
Stelle gerahmt — der Elternversatz fehlte. Aufgefallen ist es, weil die Modellseite die
|
||
Weltposition liefert und die Vorschau damit ein **anderes** Bild gezeigt haette als Play. Der
|
||
Unit-Test haelt genau diesen Unterschied fest: die Entity meldet `{x: 20, y: 10}`, gerahmt wird
|
||
bei `{x: 320, y: 210}`.
|
||
|
||
## Die Vorschau kostet nichts, solange man sie nicht sieht
|
||
|
||
Sie erfordert ein Einsammeln der ganzen Szene. Ohne Bremse liefe das bei **jeder** Auswahl-
|
||
oder Modelaenderung mit, auch waehrend der Scene-Tab offen ist — vorher tat der Game-View in
|
||
dem Fall gar nichts. `redraw()` steigt deshalb aus, solange das Widget unsichtbar ist; das
|
||
Einschalten des Tabs laeuft ohnehin ueber ein `relayout`, das per `resize` neu zeichnet.
|
||
|
||
## Belegt
|
||
|
||
Vier Unit-Tests (`tests/viewport/active-camera.test.ts`) — drei davon fallen um, wenn man die
|
||
Schalter-Bedingung oder die Weltposition entfernt (gegengeprueft). Dazu sechs E2E-Checks in
|
||
Modul 03. Der staerkste vergleicht Vorschau und Play direkt, damit "es rendert irgendwas" nicht
|
||
als Vorschau durchgeht:
|
||
|
||
```
|
||
PASS the game tab previews the scene through the active camera, without playing
|
||
– {"rendering":true,"visibleItems":2,"camera":"o3"}
|
||
PASS and the crate is really drawn there, not left as letterbox – #e0553f
|
||
PASS and it is the picture Play produces: same camera, same items, same pixel on the crate
|
||
– {…,"camera":"o3"} vs {…,"camera":"o3"}, #e0553f vs #e0553f
|
||
PASS switching the camera off empties the preview and names the reason
|
||
– {"rendering":false,"visibleItems":0,"camera":""}
|
||
PASS and undo brings the preview back without a reload
|
||
```
|
||
|
||
Der Pixel-Vergleich ist der Kern: dieselbe Farbe an derselben Bildschirmstelle wie im laufenden
|
||
Spiel. Der vierte Check liest zusaetzlich ueber `__gm.locate('No active camera')` nach, dass der
|
||
Text wirklich auf dem Schirm steht — `rendering: false` allein waere auch bei einem schwarzen
|
||
Kasten ohne Text erfuellt.
|
||
|
||
Screenshots `10c-game-preview` und `10d-no-active-camera`.
|