Skip to main content

movement/
movement.rs

1//! Movement example demonstrating character movement with arrow keys.
2//!
3//! This example shows:
4//! - Handling keyboard input for movement
5//! - Updating state based on events
6//! - Drawing a moving character on the screen
7
8use minui::prelude::*;
9use std::time::Duration;
10
11struct MovementState {
12    x: u16,
13    y: u16,
14}
15
16fn main() -> minui::Result<()> {
17    let initial_state = MovementState { x: 2, y: 2 };
18
19    let mut app = App::new(initial_state)?.with_frame_rate(Duration::from_millis(50));
20
21    app.run(
22        |state, event| {
23            let (width, height) = (80u16, 24u16); // Reasonable defaults
24
25            match event {
26                // Prefer modifier-aware key events first (the keyboard handler may emit these for most keys).
27                Event::KeyWithModifiers(k) => match k.key {
28                    KeyKind::Char('q') | KeyKind::Escape => return false,
29
30                    KeyKind::Up => {
31                        if state.y > 0 {
32                            state.y -= 1;
33                        }
34                    }
35                    KeyKind::Down => {
36                        if state.y < height - 1 {
37                            state.y += 1;
38                        }
39                    }
40                    KeyKind::Left => {
41                        if state.x > 0 {
42                            state.x -= 1;
43                        }
44                    }
45                    KeyKind::Right => {
46                        if state.x < width - 1 {
47                            state.x += 1;
48                        }
49                    }
50                    _ => {}
51                },
52
53                // Legacy fallback.
54                Event::Character('q') | Event::Escape => return false,
55                Event::KeyUp => {
56                    if state.y > 0 {
57                        state.y -= 1;
58                    }
59                }
60                Event::KeyDown => {
61                    if state.y < height - 1 {
62                        state.y += 1;
63                    }
64                }
65                Event::KeyLeft => {
66                    if state.x > 0 {
67                        state.x -= 1;
68                    }
69                }
70                Event::KeyRight => {
71                    if state.x < width - 1 {
72                        state.x += 1;
73                    }
74                }
75
76                _ => {}
77            }
78
79            true
80        },
81        |state, window| {
82            let (width, height) = window.get_size();
83
84            // Draw instructions
85            let instructions =
86                Label::new("Use arrow keys to move, 'q' to quit").with_text_color(Color::Cyan);
87            instructions.draw(window)?;
88
89            // Draw the player character
90            window.write_str_colored(
91                state.y,
92                state.x,
93                "@",
94                ColorPair::new(Color::Green, Color::Transparent),
95            )?;
96
97            // Draw boundary indicators
98            window.write_str(
99                height - 1,
100                0,
101                &format!(
102                    "Position: ({}, {}) | Terminal: {}x{}",
103                    state.x, state.y, width, height
104                ),
105            )?;
106
107            window.flush()?;
108            Ok(())
109        },
110    )?;
111
112    Ok(())
113}