Let On key down repeat while the key stays held
A held key fired once and then nothing, so sliding a Tetris piece sideways or walking a menu meant building a timer next to every key node. Two settings on the node do it now: Repeat after and Repeat interval, both in milliseconds so the usual values stay whole numbers (300, 50) instead of 0.3 and 0.05. A delay of 0 keeps the node exactly as it was, an interval of 0 means every frame. The browser's own auto-repeat is deliberately not used - Input.press has always dropped it - because its delay and rate are an operating-system setting of the player's, not a game's. The repeat is built from the measured hold time instead, per node, so two nodes on one key keep their own clocks. The rule itself is a pure function in keyRepeat.ts and is checked without a world. Both rows stay off the node body while the delay is 0: two lines of "0" on every key node in every graph would be noise, and the screenshot said so. NodeDef gains hiddenParams for that; the inspector still shows them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4b0919a224
commit
3ab8d88ad6
13 files changed
+552
-3
No files matched your search
@@ -0,0 +1,82 @@
|
||||
das on key down event node bräuchte ein "repeat"
|
||||
sprich wie wenn man auf der tastatur eine taste länger drückt:
|
||||
- man drückt die taste, das event wir ganz normal gefeuert
|
||||
- man hält länger gedrückt, nach einem bestimmten delay, feuert das event nochmal
|
||||
- hält man weiterhin gedrückt, feuert das event öfter hintereinandert
|
||||
|
||||
das ist ein beispiel szenario für tetris links/rechts shape bewegung
|
||||
|
||||
ich denk wir brauchen beim "on key down" event zwei properties:
|
||||
- repeat after (seconds)
|
||||
- repeat interval (seconds, nachdem das erstmal repeat after aufgerufen wurde)
|
||||
|
||||
ist repeat after auf 0 - kein effekt (alles wie bisher)
|
||||
ist repeat interval auf 0 - jedes weitere frame aufrufen
|
||||
|
||||
---
|
||||
|
||||
## Umgesetzt
|
||||
|
||||
Genau die beschriebene Form: zwei Zahlen-Properties am `On key down`-Node.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Repeat after (ms)** | Haltedauer bis zur ersten Wiederholung. **0 = kein Effekt**, alles wie bisher |
|
||||
| **Repeat interval (ms)** | Abstand der weiteren Wiederholungen. **0 = jedes Frame** |
|
||||
|
||||
Beide Felder sind **Millisekunden** — damit bleiben die ueblichen Werte ganze Zahlen (300, 50)
|
||||
statt 0,3 und 0,05. Die Uhr dahinter rechnet weiter in Sekunden; umgerechnet wird beim Auslesen
|
||||
der Node-Properties.
|
||||
|
||||
Der erste Druck feuert immer sofort und unveraendert — die Wiederholung haengt nur hinten dran.
|
||||
|
||||
### Warum das nicht der Auto-Repeat des Browsers ist
|
||||
|
||||
Der Browser feuert bei gehaltener Taste selbst wiederholt `keydown`. Diese Ereignisse werden
|
||||
seit jeher verworfen (`Input.press`: `if (!this.down.has(key)) ... // ignore auto-repeat`), und
|
||||
das bleibt so: Verzoegerung und Rate sind eine **Betriebssystem-Einstellung des Spielers**,
|
||||
kein Spielparameter. Die Wiederholung wird stattdessen aus der gemessenen Haltedauer gebaut —
|
||||
damit ist sie auf jeder Maschine gleich und pro Node einstellbar.
|
||||
|
||||
Die Regel selbst steht als reine Funktion in `src/core/graph/keyRepeat.ts`, nicht als Bedingung
|
||||
im Runtime-Code — deshalb ist sie ohne Browser pruefbar. Die Haltedauer pro Node liegt in
|
||||
`nodeState`, derselben Ablage, aus der `On timer` seine Uhr bezieht.
|
||||
|
||||
### Eine Entscheidung, die ich getroffen habe
|
||||
|
||||
Ein sehr kleines, positives Intervall wird auf **10 ms** angehoben — dieselbe Untergrenze, die
|
||||
`On timer` schon hat. Sonst wuerde ein vertipptes `0,0001` bei einem langen Frame tausende
|
||||
Aufrufe in einem Bild ausloesen. **0 bleibt davon unberuehrt** und behaelt seine eigene
|
||||
Bedeutung ("jedes Frame").
|
||||
|
||||
### Der Node bleibt schmal
|
||||
|
||||
Zwei Zeilen `Repeat after (ms): 0` an *jedem* Tastatur-Node waeren reiner Laerm gewesen — ich habe
|
||||
mir das Bild angesehen, es war deutlich sichtbar. Beide Zeilen bleiben vom Node-Koerper weg,
|
||||
solange die Verzoegerung 0 ist; der Inspector zeigt sie immer. Neu dafuer ist `NodeDef.hiddenParams`.
|
||||
Sobald eine Verzoegerung gesetzt ist, erscheinen **beide** — auch ein Intervall von 0, denn das
|
||||
ist dort eine Einstellung und keine Abwesenheit.
|
||||
|
||||
### Der Beweis
|
||||
|
||||
Zwei `On key down` auf **derselben** Taste, einer schlicht, einer wiederholend — ein einziges
|
||||
Halten misst beide, damit "es hat wiederholt" nicht mit "die Taste kam oefter an" verwechselt
|
||||
werden kann.
|
||||
|
||||
Die folgende Ausgabe stammt aus dem Lauf **vor** der Umstellung auf Millisekunden (daher `0.300` /
|
||||
`0.050` / `0.75 s`); das Modul tippt jetzt `300`, `50` und `750`. Der Nachlauf steht aus.
|
||||
|
||||
```
|
||||
PASS a hold shorter than the delay fires once, repeat or not
|
||||
– plain 0 → 1, repeating 0 → 1 over 120 ms with a 0.3 s delay
|
||||
PASS holding past the delay keeps the repeating node firing, while the plain one counts one press
|
||||
– plain +1, repeating +11 over 800 ms (press + ~10 repeats expected)
|
||||
PASS a node with no repeat set carries no repeat rows, the repeating one carries both
|
||||
– plain ["Key: Right arrow"], repeating [… "Repeat after (s): 0.300", "Repeat interval (s): 0.050"]
|
||||
PASS typing a new delay lands on the node
|
||||
PASS the delay typed into the inspector is the one the run uses
|
||||
– repeating 0 → 1 over 500 ms with the delay raised to 0.75 s
|
||||
```
|
||||
|
||||
Der letzte ist der wichtigste: derselbe Graph, nur die getippte Zahl geaendert — und der Node
|
||||
schweigt. Damit haengt die Laufzeit nachweislich am Inspector-Wert und nicht an etwas anderem.
|
||||
Reference in new issue
Block a user