69 lines
2.2 KiB
Markdown
Executable File
69 lines
2.2 KiB
Markdown
Executable File
# Input Manager
|
|
|
|
## Current state
|
|
|
|
Input is fully decoupled from the windowing backend. `client/src/input.rs` owns all input
|
|
types. `main.rs` translates `pbio::Event::Key` events into `GameAction` values each frame and
|
|
stores them in an `InputState`. `game::update()` receives a `&InputState` and queries it with
|
|
three distinct semantics. (The platform/windowing layer lives in the external `pbio` crate;
|
|
game code only ever sees `pbio::Key`, never a raw backend type.)
|
|
|
|
## Architecture
|
|
|
|
### `GameAction` — `client/src/input.rs`
|
|
|
|
Logical actions the game cares about. Game code never sees backend key types.
|
|
|
|
```rust
|
|
pub enum GameAction { Up, Down, Left, Right, Confirm, Cancel }
|
|
```
|
|
|
|
### `InputMap` — `client/src/input.rs`
|
|
|
|
Translates a `pbio::Key` to an `Option<GameAction>`. All key bindings live here.
|
|
|
|
| Key | Action |
|
|
|------------------|---------|
|
|
| Up / W | Up |
|
|
| Down / S | Down |
|
|
| Left / A | Left |
|
|
| Right / D | Right |
|
|
| Enter | Confirm |
|
|
| Escape | Cancel |
|
|
|
|
### `InputState` — `client/src/input.rs`
|
|
|
|
Three internal buffers, populated from `pbio::Event::Key` events in `main.rs`:
|
|
|
|
| Buffer | Lifetime | Populated by |
|
|
|------------|----------------|---------------------------|
|
|
| `pressed` | current frame | key-down event |
|
|
| `held` | until released | key-down; cleared on up |
|
|
| `released` | current frame | key-up event |
|
|
|
|
`clear()` is called after `game::update()` each frame. It clears `pressed` and `released`;
|
|
`held` persists until the corresponding key-up event arrives.
|
|
|
|
#### Query API
|
|
|
|
```rust
|
|
input.button_pressed(action) // true only on the frame the key went down
|
|
input.button_held(action) // true every frame the key is physically held
|
|
input.button_released(action) // true only on the frame the key was released
|
|
```
|
|
|
|
## Data flow per frame
|
|
|
|
```
|
|
pbio::Event::Key
|
|
→ InputMap::translate(key)
|
|
→ InputState::push / InputState::release
|
|
→ game.update(&mut framebuffer, dt, &input_state) -> Option<GameSignal>
|
|
→ input_state.clear()
|
|
```
|
|
|
|
## Open questions
|
|
|
|
- Should modifier keys (Shift, Ctrl) produce distinct actions, or be handled in the mapping?
|
|
- How do we prepare for key rebinding?
|