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>
20 lines
827 B
TypeScript
20 lines
827 B
TypeScript
import type { NodeDef } from '../../NodeRegistry';
|
|
import { asNumber } from '../../values';
|
|
import { exec, keyParam } from '../shared';
|
|
|
|
export const OnKeyDown: NodeDef = {
|
|
type: 'OnKeyDown',
|
|
label: 'On key down',
|
|
category: 'event',
|
|
description: 'Runs when the key is pressed, and again while it stays held if a repeat is set.',
|
|
inputs: [],
|
|
outputs: [exec()],
|
|
params: [
|
|
keyParam,
|
|
{ key: 'repeatAfter', label: 'Repeat after (ms)', kind: 'number', default: 0, min: 0, step: 50 },
|
|
{ key: 'repeatInterval', label: 'Repeat interval (ms)', kind: 'number', default: 0, min: 0, step: 10 },
|
|
],
|
|
// Both rows go together: with no delay there is no repeat, so the interval is not in play either.
|
|
hiddenParams: (params) => (asNumber(params.repeatAfter ?? 0) > 0 ? [] : ['repeatAfter', 'repeatInterval']),
|
|
};
|