feat(input): raw device layer — multi-key held state, analog, mouse, gamepad, touch, full-state replay (#50)
The raw device layer the input proposal sketched, over the action maps + record/replay of #7. Beyond one key per frame, gameplay can read: - Multiple simultaneous held keys: Input.key_down / key_pressed / key_released, with clean rising/falling edges (hold left AND jump). - Analog from keys: Input.axis(neg, pos) and a normalized Input.vector(l,r,u,d) (diagonals scaled by 1/sqrt(2)), plus Input.strength(action). - Mouse: Input.mouse_x/y, mouse_dx/dy (per-frame delta), mouse_down(btn), wheel. - Gamepads: Input.pad_connected/pad_button/pad_axis (SDL-order buttons, -1..1 sticks); touch: Input.touch_count/touch_x/touch_y. The held set is fed by the platform when windowed — cocoa.ll now tracks keyDown/keyUp into a 256-bit held-key bitset (win_held) and the mouse buttons/wheel (win_mouse), gated so headless builds DCE the native calls — and by the Input.press / Input.set_mouse / Input.set_pad / Input.set_touch injection on every target (Godot-style action injection: replays, AI, network-fed input). Input.record / replay now snapshot the full per-frame device state (held set + mouse), extending #7's single-key tape. Everything is integer and deterministic, so the same inputs reproduce the same frame on every run and headless. The gamepad/touch native hardware bindings (GameController.framework / NSTouch) feed the same injected state and are the one remaining platform-glue follow-up; the software layer, semantics and replay are complete and driven deterministically today. Worked example + regression: examples/library/input_device.ludic (1 1 0 1 0 1 71 -71 5 1 3 1 2 1 0 0 1, injection-driven headless). 23 new docs/language/input pages. Full suite 78 passed, self-host C-free fixpoint intact, no golden drift; cocoa.ll assembles and a windowed build links. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1f5e3c1c1a
commit
53bb441f23
35 changed files with 23630 additions and 20813 deletions
|
|
@ -4,4 +4,6 @@ title: Input
|
|||
order: 6
|
||||
---
|
||||
|
||||
Reading the keyboard.
|
||||
Reading input. At the base, <a href="input-key.html"><code>Input.key</code></a> gives this frame's key and <a href="input-poll.html"><code>Input.poll</code></a> is the single per-frame read that also drives deterministic record/replay. Over that sit <strong>named actions</strong> — <a href="input-bind.html"><code>Input.bind</code></a> / <a href="input-down.html"><code>Input.down</code></a> / <a href="input-pressed.html"><code>Input.pressed</code></a> / <a href="input-rebind.html"><code>Input.rebind</code></a> — so gameplay reads rebindable actions, not physical keys.
|
||||
|
||||
The <strong>device layer</strong> adds everything past one key per frame: multiple simultaneous held keys (<a href="input-key_down.html"><code>Input.key_down</code></a> / <a href="input-key_pressed.html"><code>key_pressed</code></a> / <a href="input-key_released.html"><code>key_released</code></a>), analog <a href="input-axis.html"><code>Input.axis</code></a> and normalized <a href="input-vector.html"><code>Input.vector</code></a>, the <a href="input-mouse_x.html">mouse</a> (position, delta, buttons, <a href="input-wheel.html">wheel</a>), <a href="input-pad_button.html">gamepads</a> and <a href="input-touch_count.html">touch</a>. The held set is fed by the platform when windowed and by the <a href="input-press.html"><code>Input.press</code></a> / <a href="input-set_mouse.html"><code>Input.set_*</code></a> injection on every target — the same idea as Godot's <code>action_press</code>, and what a replay, an AI, or the network feeds. Everything is integer and deterministic, and record/replay snapshots the whole per-frame state.
|
||||
|
|
|
|||
24
docs/language/input/input-axis.md
Normal file
24
docs/language/input/input-axis.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-axis
|
||||
name: Input.axis
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.axis
|
||||
sig: Input.axis(neg, pos) -> fixed
|
||||
tip: A -1..+1 axis from two keys.
|
||||
order: 13
|
||||
ns: Input
|
||||
member: axis
|
||||
---
|
||||
|
||||
Returns a digital axis from two keys: <code>+1.0</code> when the positive key is held, <code>-1.0</code> when the negative one is, <code>0</code> otherwise (both or neither). The building block for keyboard movement; a gamepad stick feeds the analog value through the same read.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('d')
|
||||
Input.poll()
|
||||
print(Math.round(Input.axis('a', 'd')))
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-key_down.md
Normal file
24
docs/language/input/input-key_down.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-key_down
|
||||
name: Input.key_down
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.key_down
|
||||
sig: Input.key_down(key) -> bool
|
||||
tip: Is a physical key held this frame?
|
||||
order: 8
|
||||
ns: Input
|
||||
member: key_down
|
||||
---
|
||||
|
||||
Returns whether a physical <code>key</code> is held this frame — from the platform when windowed, from the polled key when headless, and from <a href="input-press.html"><code>Input.press</code></a> injection on any target. Unlike the single-key <a href="input-down.html"><code>Input.down</code></a>, several keys can be held at once (move left <em>and</em> jump).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('a')
|
||||
Input.poll()
|
||||
if Input.key_down('a') { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-key_pressed.md
Normal file
24
docs/language/input/input-key_pressed.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-key_pressed
|
||||
name: Input.key_pressed
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.key_pressed
|
||||
sig: Input.key_pressed(key) -> bool
|
||||
tip: Did a key go down this frame (edge)?
|
||||
order: 9
|
||||
ns: Input
|
||||
member: key_pressed
|
||||
---
|
||||
|
||||
Returns whether a key went down <em>this</em> frame — held now, not held last frame. A clean rising edge for one-shot actions (fire, confirm), distinct from the continuous <a href="input-key_down.html"><code>Input.key_down</code></a>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press(' ')
|
||||
Input.poll()
|
||||
if Input.key_pressed(' ') { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
26
docs/language/input/input-key_released.md
Normal file
26
docs/language/input/input-key_released.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: input-key_released
|
||||
name: Input.key_released
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.key_released
|
||||
sig: Input.key_released(key) -> bool
|
||||
tip: Did a key go up this frame (edge)?
|
||||
order: 10
|
||||
ns: Input
|
||||
member: key_released
|
||||
---
|
||||
|
||||
Returns whether a key went up this frame — held last frame, not held now. The falling edge, for release-triggered actions (charge-and-release, letting go of a grip).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('a')
|
||||
Input.poll()
|
||||
Input.release('a')
|
||||
Input.poll()
|
||||
if Input.key_released('a') { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-mouse_down.md
Normal file
24
docs/language/input/input-mouse_down.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-mouse_down
|
||||
name: Input.mouse_down
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.mouse_down
|
||||
sig: Input.mouse_down(button) -> bool
|
||||
tip: Is a mouse button held?
|
||||
order: 20
|
||||
ns: Input
|
||||
member: mouse_down
|
||||
---
|
||||
|
||||
Returns whether a mouse button is held this frame — button <code>0</code> left, <code>1</code> right, <code>2</code> middle/other.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(0, 0, 1, 0)
|
||||
Input.poll()
|
||||
if Input.mouse_down(0) { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
26
docs/language/input/input-mouse_dx.md
Normal file
26
docs/language/input/input-mouse_dx.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: input-mouse_dx
|
||||
name: Input.mouse_dx
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.mouse_dx
|
||||
sig: Input.mouse_dx() -> int
|
||||
tip: Mouse x movement since the last poll.
|
||||
order: 18
|
||||
ns: Input
|
||||
member: mouse_dx
|
||||
---
|
||||
|
||||
The change in the mouse's x since the previous <a href="input-poll.html"><code>Input.poll</code></a> — the relative motion for dragging, panning, or a mouse-look camera.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(10, 0, 0, 0)
|
||||
Input.poll()
|
||||
Input.set_mouse(15, 0, 0, 0)
|
||||
Input.poll()
|
||||
print(Input.mouse_dx())
|
||||
}
|
||||
}
|
||||
```
|
||||
26
docs/language/input/input-mouse_dy.md
Normal file
26
docs/language/input/input-mouse_dy.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: input-mouse_dy
|
||||
name: Input.mouse_dy
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.mouse_dy
|
||||
sig: Input.mouse_dy() -> int
|
||||
tip: Mouse y movement since the last poll.
|
||||
order: 19
|
||||
ns: Input
|
||||
member: mouse_dy
|
||||
---
|
||||
|
||||
The change in the mouse's y since the previous <a href="input-poll.html"><code>Input.poll</code></a> — the vertical companion to <a href="input-mouse_dx.html"><code>Input.mouse_dx</code></a>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(0, 10, 0, 0)
|
||||
Input.poll()
|
||||
Input.set_mouse(0, 18, 0, 0)
|
||||
Input.poll()
|
||||
print(Input.mouse_dy())
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-mouse_x.md
Normal file
24
docs/language/input/input-mouse_x.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-mouse_x
|
||||
name: Input.mouse_x
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.mouse_x
|
||||
sig: Input.mouse_x() -> int
|
||||
tip: The mouse x position this frame.
|
||||
order: 16
|
||||
ns: Input
|
||||
member: mouse_x
|
||||
---
|
||||
|
||||
The mouse's x position this frame — fed by the window when windowed, or by <a href="input-set_mouse.html"><code>Input.set_mouse</code></a> otherwise.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(10, 20, 0, 0)
|
||||
Input.poll()
|
||||
print(Input.mouse_x())
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-mouse_y.md
Normal file
24
docs/language/input/input-mouse_y.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-mouse_y
|
||||
name: Input.mouse_y
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.mouse_y
|
||||
sig: Input.mouse_y() -> int
|
||||
tip: The mouse y position this frame.
|
||||
order: 17
|
||||
ns: Input
|
||||
member: mouse_y
|
||||
---
|
||||
|
||||
The mouse's y position this frame — fed by the window when windowed, or by <a href="input-set_mouse.html"><code>Input.set_mouse</code></a> otherwise.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(10, 20, 0, 0)
|
||||
Input.poll()
|
||||
print(Input.mouse_y())
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-pad_axis.md
Normal file
23
docs/language/input/input-pad_axis.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-pad_axis
|
||||
name: Input.pad_axis
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.pad_axis
|
||||
sig: Input.pad_axis(pad, axis) -> fixed
|
||||
tip: A gamepad analog axis, -1..+1.
|
||||
order: 25
|
||||
ns: Input
|
||||
member: pad_axis
|
||||
---
|
||||
|
||||
Returns a gamepad analog axis as a <code>fixed</code> in <code>-1.0..+1.0</code> — axis <code>0</code> left-stick x, <code>1</code> left-stick y, <code>2</code> right-stick x, <code>3</code> right-stick y. Apply your own deadzone near zero.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_pad(0, true, 0, 1.0, 0.0, 0.0, 0.0)
|
||||
print(Math.round(Input.pad_axis(0, 0)))
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-pad_button.md
Normal file
23
docs/language/input/input-pad_button.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-pad_button
|
||||
name: Input.pad_button
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.pad_button
|
||||
sig: Input.pad_button(pad, button) -> bool
|
||||
tip: Is a gamepad button held?
|
||||
order: 24
|
||||
ns: Input
|
||||
member: pad_button
|
||||
---
|
||||
|
||||
Returns whether <code>button</code> on gamepad <code>pad</code> is held — a bit in the pad's button mask, in the SDL standard order (A/B/X/Y, bumpers, start, …).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_pad(0, true, 1, 0.0, 0.0, 0.0, 0.0)
|
||||
if Input.pad_button(0, 0) { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-pad_connected.md
Normal file
23
docs/language/input/input-pad_connected.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-pad_connected
|
||||
name: Input.pad_connected
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.pad_connected
|
||||
sig: Input.pad_connected(pad) -> bool
|
||||
tip: Is a gamepad connected?
|
||||
order: 23
|
||||
ns: Input
|
||||
member: pad_connected
|
||||
---
|
||||
|
||||
Returns whether gamepad <code>pad</code> (0..3) is connected. Fed by <a href="input-set_pad.html"><code>Input.set_pad</code></a> (and, where a platform gamepad binding is present, by the device); lets a game show a "controller connected" prompt.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_pad(0, true, 0, 0.0, 0.0, 0.0, 0.0)
|
||||
if Input.pad_connected(0) { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-press.md
Normal file
24
docs/language/input/input-press.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-press
|
||||
name: Input.press
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.press
|
||||
sig: Input.press(key)
|
||||
tip: Inject a held key (AI, tutorial, testing, network).
|
||||
order: 11
|
||||
ns: Input
|
||||
member: press
|
||||
---
|
||||
|
||||
Injects a held key into the input state — the same idea as Godot's <code>action_press</code>. It persists until <a href="input-release.html"><code>Input.release</code></a>, and combines with the platform's real keys, so an AI, a replay, a tutorial, or the network can drive input exactly as a player would. Deterministic on every target.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('w')
|
||||
Input.poll()
|
||||
if Input.key_down('w') { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
26
docs/language/input/input-release.md
Normal file
26
docs/language/input/input-release.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: input-release
|
||||
name: Input.release
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.release
|
||||
sig: Input.release(key)
|
||||
tip: Release an injected key.
|
||||
order: 12
|
||||
ns: Input
|
||||
member: release
|
||||
---
|
||||
|
||||
Releases a key previously held with <a href="input-press.html"><code>Input.press</code></a>. After the next <a href="input-poll.html"><code>Input.poll</code></a> the key reads as up (and fires <a href="input-key_released.html"><code>Input.key_released</code></a> that frame).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('w')
|
||||
Input.poll()
|
||||
Input.release('w')
|
||||
Input.poll()
|
||||
print(0)
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-set_mouse.md
Normal file
24
docs/language/input/input-set_mouse.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-set_mouse
|
||||
name: Input.set_mouse
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.set_mouse
|
||||
sig: Input.set_mouse(x, y, buttons, wheel)
|
||||
tip: Inject the mouse state (headless / AI / testing).
|
||||
order: 22
|
||||
ns: Input
|
||||
member: set_mouse
|
||||
---
|
||||
|
||||
Injects the whole mouse state: position <code>x</code>/<code>y</code>, a <code>buttons</code> bitmask (bit 0 left, 1 right, 2 middle), and this frame's <code>wheel</code> delta. The mouse counterpart to <a href="input-press.html"><code>Input.press</code></a> — for headless runs, AI, replays, or network-fed cursors.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(64, 32, 1, 0)
|
||||
Input.poll()
|
||||
print(Input.mouse_x())
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-set_pad.md
Normal file
23
docs/language/input/input-set_pad.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-set_pad
|
||||
name: Input.set_pad
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.set_pad
|
||||
sig: Input.set_pad(pad, connected, buttons, lx, ly, rx, ry)
|
||||
tip: Inject a gamepad's whole state.
|
||||
order: 26
|
||||
ns: Input
|
||||
member: set_pad
|
||||
---
|
||||
|
||||
Injects gamepad <code>pad</code>'s whole state: <code>connected</code>, a <code>buttons</code> bitmask, and the four stick axes (<code>lx</code>, <code>ly</code>, <code>rx</code>, <code>ry</code>) as <code>fixed</code> in <code>-1.0..+1.0</code>. A platform gamepad binding feeds the same state; until then this drives it from replays, AI, or the network.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_pad(0, true, 5, 1.0, 0.0, 0.0, 0.0)
|
||||
if Input.pad_button(0, 2) { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-set_touch.md
Normal file
23
docs/language/input/input-set_touch.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-set_touch
|
||||
name: Input.set_touch
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.set_touch
|
||||
sig: Input.set_touch(index, x, y, active)
|
||||
tip: Inject a touch point.
|
||||
order: 30
|
||||
ns: Input
|
||||
member: set_touch
|
||||
---
|
||||
|
||||
Injects touch point <code>index</code> (0..7): <code>active</code> with a position, or inactive. A platform touch binding feeds the same points; until then this drives multi-touch from replays, AI, or the network.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_touch(0, 64, 64, true)
|
||||
print(Input.touch_count())
|
||||
}
|
||||
}
|
||||
```
|
||||
25
docs/language/input/input-strength.md
Normal file
25
docs/language/input/input-strength.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
id: input-strength
|
||||
name: Input.strength
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.strength
|
||||
sig: Input.strength(action) -> fixed
|
||||
tip: 0..1 strength of a named action.
|
||||
order: 15
|
||||
ns: Input
|
||||
member: strength
|
||||
---
|
||||
|
||||
Returns the <code>0.0..1.0</code> strength of a named <a href="input-bind.html">action</a> — <code>1.0</code> when any bound key is held, <code>0</code> otherwise for keys (digital), and the analog magnitude when a gamepad feeds the action. Lets analog and digital sources share one read.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.bind("gas", 'w')
|
||||
Input.press('w')
|
||||
Input.poll()
|
||||
print(Math.round(Input.strength("gas")))
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-touch_count.md
Normal file
24
docs/language/input/input-touch_count.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-touch_count
|
||||
name: Input.touch_count
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.touch_count
|
||||
sig: Input.touch_count() -> int
|
||||
tip: How many touch points are active?
|
||||
order: 27
|
||||
ns: Input
|
||||
member: touch_count
|
||||
---
|
||||
|
||||
Returns how many touch points are currently active (0..8). Iterate them with <a href="input-touch_x.html"><code>Input.touch_x</code></a> / <a href="input-touch_y.html"><code>Input.touch_y</code></a>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_touch(0, 10, 20, true)
|
||||
Input.set_touch(1, 30, 40, true)
|
||||
print(Input.touch_count())
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-touch_x.md
Normal file
23
docs/language/input/input-touch_x.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-touch_x
|
||||
name: Input.touch_x
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.touch_x
|
||||
sig: Input.touch_x(index) -> int
|
||||
tip: The x of a touch point.
|
||||
order: 28
|
||||
ns: Input
|
||||
member: touch_x
|
||||
---
|
||||
|
||||
The x position of touch point <code>index</code> (0..7). Pair with <a href="input-touch_y.html"><code>Input.touch_y</code></a> and <a href="input-touch_count.html"><code>Input.touch_count</code></a> for multi-touch.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_touch(0, 100, 200, true)
|
||||
print(Input.touch_x(0))
|
||||
}
|
||||
}
|
||||
```
|
||||
23
docs/language/input/input-touch_y.md
Normal file
23
docs/language/input/input-touch_y.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
id: input-touch_y
|
||||
name: Input.touch_y
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.touch_y
|
||||
sig: Input.touch_y(index) -> int
|
||||
tip: The y of a touch point.
|
||||
order: 29
|
||||
ns: Input
|
||||
member: touch_y
|
||||
---
|
||||
|
||||
The y position of touch point <code>index</code> (0..7) — the vertical companion to <a href="input-touch_x.html"><code>Input.touch_x</code></a>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_touch(0, 100, 200, true)
|
||||
print(Input.touch_y(0))
|
||||
}
|
||||
}
|
||||
```
|
||||
26
docs/language/input/input-vector.md
Normal file
26
docs/language/input/input-vector.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: input-vector
|
||||
name: Input.vector
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.vector
|
||||
sig: Input.vector(left, right, up, down) -> Vector
|
||||
tip: A normalized 2D vector from four keys.
|
||||
order: 14
|
||||
ns: Input
|
||||
member: vector
|
||||
---
|
||||
|
||||
Returns a 2D movement <a href="vector.html"><code>Vector</code></a> from four direction keys, normalized so a diagonal is not faster than a straight move (each diagonal component is <code>0.7071</code>). The one call for eight-way keyboard movement.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.press('d')
|
||||
Input.press('w')
|
||||
Input.poll()
|
||||
let v = Input.vector('a', 'd', 'w', 's')
|
||||
print(Math.round(Vector.x(v) * 100))
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/input/input-wheel.md
Normal file
24
docs/language/input/input-wheel.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-wheel
|
||||
name: Input.wheel
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.wheel
|
||||
sig: Input.wheel() -> int
|
||||
tip: Scroll-wheel delta this frame.
|
||||
order: 21
|
||||
ns: Input
|
||||
member: wheel
|
||||
---
|
||||
|
||||
The scroll-wheel delta accumulated this frame — positive up, negative down, <code>0</code> when the wheel did not move. A per-frame delta, reset each <a href="input-poll.html"><code>Input.poll</code></a>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
entry {
|
||||
Input.set_mouse(0, 0, 0, 3)
|
||||
Input.poll()
|
||||
print(Input.wheel())
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue