docs: Umsetzungsplan für die Minimap, Spec nachgeschärft
Vier Aufgaben: Chunk-Namen in JavaScript und Python mit gemeinsamem Beispielsatz; Kartenbild, Begehbarkeitsmaske und map.json aus overview.py; reine Kartenmathematik mit Tests; Kartenkomponente und Einhängen mit Browser-Abnahme. Die Spec bekommt dabei drei Präzisierungen, die sich erst beim Lesen des Codes ergeben haben: die Namensnennung muss über der Karte liegen (Lizenzpflicht), die Veraltungsprüfung erkennt nicht jede Änderung, und die Eingabesperre stoppt Mausereignisse auf der Karte erst an deren Wurzel, weil ein Stopp in der Capture-Phase auch den eigenen Canvas taub machen würde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0767375fe
commit
44108f94f4
2 files changed
+1338
-5
No files matched your search
@@ -46,15 +46,16 @@ Die Kartenkomponente bekommt ihre Abhängigkeiten übergeben, statt selbst in Co
|
||||
|
||||
```js
|
||||
createMap({
|
||||
mapInfo, // Inhalt von map.json
|
||||
manifest, // für den Fingerabdruck-Vergleich
|
||||
getPosition, // () => { x, z } in three-Koordinaten
|
||||
getHeading, // () => Winkel in Radiant
|
||||
getHeading, // () => Winkel in Radiant, 0 = Norden, im Uhrzeigersinn
|
||||
getVehicles, // () => [{ x, z, heading, occupied }]
|
||||
onTeleport, // ({ x, z }) => void
|
||||
baseUrl, // Verzeichnis mit map.json, map.png, map-walkable.png und manifest.json
|
||||
}) // -> { open(), close(), toggle(), isOpen() }
|
||||
```
|
||||
|
||||
Die Karte lädt `map.json`, beide Bilder und das Manifest selbst, und zwar erst beim ersten Öffnen. So bricht eine fehlende Kartendatei nicht den Spielstart, sondern zeigt ihren Hinweis erst, wenn jemand M drückt. Das Manifest liest sie als **Rohbytes**: der Fingerabdruck in `map.json` ist über die Datei gebildet, ein bereits geparstes und neu serialisiertes Objekt ergäbe einen anderen Wert.
|
||||
|
||||
## Koordinaten
|
||||
|
||||
three.js (x, z) → Welt (x, y = −z) → Kartenpixel:
|
||||
@@ -91,7 +92,7 @@ name(i, j) = "ABCDEFGHIJKL"[i] + (j + 1)
|
||||
**Auf der Karte:**
|
||||
- Rasterlinien an allen Chunk-Grenzen.
|
||||
- Der Name steht in der Mitte jedes Chunks, sobald der Chunk auf dem Bildschirm mindestens 40 px breit ist; darunter nur die Linien. Beim Öffnen passt der ganze Ausschnitt ins Fenster, dann ist jeder Chunk auf gängigen Bildschirmen breit genug.
|
||||
- Unter dem Mauszeiger eine Anzeige mit Chunk-Name und Weltkoordinate, etwa `C10 · x 412 / y 1830`. Die Koordinate erlaubt, eine Stelle innerhalb eines Chunks genau zu benennen.
|
||||
- Eine feste Anzeige unten rechts nennt Chunk-Name und Weltkoordinate der Stelle unter dem Mauszeiger, etwa `C10 · x 412 / y 1830`. Die Koordinate erlaubt, eine Stelle innerhalb eines Chunks genau zu benennen.
|
||||
- Der Chunk, in dem der Spieler gerade steht, ist hervorgehoben und sein Name steht fest in einer Ecke der Karte.
|
||||
|
||||
## Anbindung an vorhandene Funktionen
|
||||
@@ -109,7 +110,8 @@ name(i, j) = "ABCDEFGHIJKL"[i] + (j + 1)
|
||||
- **Steuerung ruht, Welt läuft.** Solange die Karte offen ist, erreichen Tastatur- und Mausereignisse die Figur nicht; Streaming, Fahrzeugphysik und Animation laufen weiter.
|
||||
|
||||
Umsetzung, am Quelltext des Controllers belegt: `InputSystem` registriert `keydown`, `keyup`, `mousemove` und `click` auf `window` in der Bubble-Phase.
|
||||
- Die Karte registriert beim Öffnen Listener auf `window` **in der Capture-Phase**, die diese Ereignisse mit `stopPropagation()` abfangen, und entfernt sie beim Schließen wieder. Die eigenen Kartenereignisse auf dem Canvas bleiben davon unberührt.
|
||||
- Die Karte registriert Listener auf `window` **in der Capture-Phase**, die nur bei offener Karte wirken. Tastaturereignisse fängt sie dort vollständig ab (und wertet M und Esc selbst aus). Mausereignisse, deren Ziel **außerhalb** der Karte liegt, fängt sie dort ab; Mausereignisse **auf** der Karte lässt sie bis zum Canvas durch und stoppt sie an der Kartenwurzel in der Bubble-Phase, bevor sie `window` erreichen. Ein Stopp schon in der Capture-Phase auf `window` würde sonst auch den eigenen Canvas-Listenern die Ereignisse nehmen.
|
||||
- Die Listener bleiben dauerhaft registriert statt beim Öffnen hinzugefügt und beim Schließen entfernt zu werden: M muss bei geschlossener Karte ohnehin gehört werden, und ein vergessenes Entfernen kann so nicht passieren.
|
||||
- Beim Öffnen wird einmal `window.dispatchEvent(new Event("blur"))` ausgelöst. Das ruft im Controller `resetKeys()` auf, damit eine beim Drücken von M gehaltene Bewegungstaste nicht hängen bleibt und die Figur weiterlaufen lässt.
|
||||
- **Nicht** `unbindEvents()` verwenden: es setzt `isupdate = false` und hält damit die gesamte Figurenaktualisierung an, nicht nur die Eingabe. Das widerspräche der Entscheidung, dass die Welt weiterläuft.
|
||||
- **Zoomen:** Mausrad, um den Mauszeiger herum, von „ganzer Ausschnitt passt ins Fenster" bis vierfach.
|
||||
@@ -128,6 +130,22 @@ name(i, j) = "ABCDEFGHIJKL"[i] + (j + 1)
|
||||
| `map-walkable.png` lässt sich nicht laden | Anschauen, Zoomen und Verschieben funktionieren. Klick zum Hinspringen ist abgeschaltet, ein Hinweis nennt den Grund. |
|
||||
| `map.json` fehlt oder ist ungültig | Wie fehlendes Kartenbild: ohne Maßstab und Grenzen lässt sich nichts korrekt platzieren. |
|
||||
| `manifest_sha256` passt nicht zum geladenen Manifest | Die Karte funktioniert vollständig, zeigt aber sichtbar „Karte veraltet — `overview.py` erneut ausführen". |
|
||||
| Kein sicherer Kontext (Aufruf über eine LAN-Adresse statt `localhost`) | `crypto.subtle` fehlt dort. Die Veraltungsprüfung entfällt still, alles andere funktioniert. |
|
||||
|
||||
**Grenze der Veraltungsprüfung:** Der Fingerabdruck erkennt jede Änderung am Manifest — Klassenanteile, Chunk-Liste, Namensnennung. Eine Änderung, die nur Chunk-Inhalte betrifft, ohne das Manifest zu berühren, bleibt unerkannt; genau so eine war die Mindestbreite für Gebäude. Diese Lücke schließt sich erst, wenn die Kartenerzeugung in `run.py` hängt und damit gar nicht mehr veralten kann.
|
||||
|
||||
## Namensnennung
|
||||
|
||||
Die Namensnennung bleibt auch bei offener Karte sichtbar. Das ist Lizenzpflicht, und die Karte ist selbst aus den CC-BY-4.0-Kacheln abgeleitet. Stapelordnung von oben nach unten:
|
||||
|
||||
| Ebene | `z-index` |
|
||||
|---|---|
|
||||
| Namensnennung `.attribution` | 2000 (heute 10, wird angehoben) |
|
||||
| Kartenüberlagerung | 1500 |
|
||||
| lil-gui-Panel | 1001 (Vorgabe von lil-gui) |
|
||||
| Spiel-Canvas | Grundebene |
|
||||
|
||||
Die Namensnennung steht unten links; die Koordinatenanzeige der Karte steht deshalb unten **rechts**, damit sich beide auf schmalen Fenstern nicht überdecken.
|
||||
|
||||
## Prüfung
|
||||
|
||||
|
||||
Reference in new issue
Block a user