;;;; raylib [core] example - input keys ;;;; ;;;; examples/core/core_input_keys.c. Faithful, and the only thing worth noting ;;;; is a Flan rule rather than a raylib one. ;;;; ;;;; The C moves the ball by writing `ballPosition.x += 2.0f` on a local ;;;; struct. Flan has the same thing — a local IS an assignable place ;;;; (spec-memory.md) — but the local has to be a `once` here rather than a ;;;; `let` inside the loop, because a `let` binding is rebound every iteration ;;;; and the position has to survive between frames. The C's variable is ;;;; outside its while loop for the same reason; this is that, spelled with the ;;;; storage the language has. ;;;; ;;;; `ball.x = ...` works on a struct field of a global: a field of an ;;;; assignable place is itself one. import rl "vendor:raylib" const screen-width = 800 const screen-height = 450 once ball: rl/Vector2 fn main() -> () rl/init-window(screen-width, screen-height, "raylib [core] example - input keys") defer rl/close-window() ball = rl/Vector2{.x f32(screen-width / 2) .y f32(screen-height / 2)} rl/set-target-fps(60) until rl/window-should-close() ;; Update. is-key-down and not is-key-pressed: this is meant to repeat for as ;; long as the key is held, which is the whole difference between the two. if rl/is-key-down(:key-right) ball.x += 2.0 if rl/is-key-down(:key-left) ball.x -= 2.0 if rl/is-key-down(:key-up) ball.y -= 2.0 if rl/is-key-down(:key-down) ball.y += 2.0 ;; Draw rl/with-drawing: rl/clear-background(rl/raywhite) rl/draw-text("move the ball with arrow keys", 10, 10, 20, rl/darkgray) rl/draw-circle-v(ball, 50.0, rl/maroon)