use keyboard_codes::{
current_platform, parse_keyboard_input, Key, KeyboardInput, Modifier, Platform,
};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq)]
enum GameAction {
MoveForward,
MoveBackward,
MoveLeft,
MoveRight,
Jump,
Sprint,
Crouch,
Interact,
Attack,
Reload,
Weapon1,
Weapon2,
Weapon3,
}
struct GameInputMapper {
key_bindings: HashMap<Key, GameAction>, modifier_bindings: HashMap<Modifier, GameAction>, platform: Platform,
}
impl GameInputMapper {
fn new(platform: Platform) -> Self {
let mut key_bindings = HashMap::new();
let mut modifier_bindings = HashMap::new();
Self::add_key_binding(&mut key_bindings, "w", GameAction::MoveForward);
Self::add_key_binding(&mut key_bindings, "s", GameAction::MoveBackward);
Self::add_key_binding(&mut key_bindings, "a", GameAction::MoveLeft);
Self::add_key_binding(&mut key_bindings, "d", GameAction::MoveRight);
Self::add_key_binding(&mut key_bindings, "space", GameAction::Jump);
Self::add_key_binding(&mut key_bindings, "e", GameAction::Interact);
Self::add_key_binding(&mut key_bindings, "f", GameAction::Attack);
Self::add_key_binding(&mut key_bindings, "r", GameAction::Reload);
Self::add_key_binding(&mut key_bindings, "1", GameAction::Weapon1);
Self::add_key_binding(&mut key_bindings, "2", GameAction::Weapon2);
Self::add_key_binding(&mut key_bindings, "3", GameAction::Weapon3);
Self::add_modifier_binding(&mut modifier_bindings, "shift", GameAction::Sprint);
Self::add_modifier_binding(&mut modifier_bindings, "ctrl", GameAction::Crouch);
Self {
key_bindings,
modifier_bindings,
platform,
}
}
fn add_key_binding(bindings: &mut HashMap<Key, GameAction>, input: &str, action: GameAction) {
match parse_keyboard_input(input) {
Ok(KeyboardInput::Key(key)) => {
bindings.insert(key, action);
println!(" 绑定: '{}' -> {:?}", input, action);
}
Ok(KeyboardInput::Modifier(_)) => {
eprintln!("警告: '{}' 是修饰键,请使用 add_modifier_binding", input);
}
Err(e) => {
eprintln!("警告: 无法解析键绑定 '{}': {}", input, e);
}
}
}
fn add_modifier_binding(
bindings: &mut HashMap<Modifier, GameAction>,
input: &str,
action: GameAction,
) {
match parse_keyboard_input(input) {
Ok(KeyboardInput::Modifier(modifier)) => {
bindings.insert(modifier, action);
println!(" 绑定: '{}' -> {:?}", input, action);
}
Ok(KeyboardInput::Key(_)) => {
eprintln!("警告: '{}' 是普通键,请使用 add_key_binding", input);
}
Err(e) => {
eprintln!("警告: 无法解析修饰键绑定 '{}': {}", input, e);
}
}
}
fn handle_key_event(&self, vk_code: usize) -> Option<GameAction> {
if let Some(keyboard_input) = KeyboardInput::from_code(vk_code, self.platform) {
match keyboard_input {
KeyboardInput::Key(key) => {
if let Some(action) = self.key_bindings.get(&key) {
return Some(*action);
}
}
KeyboardInput::Modifier(modifier) => {
if let Some(action) = self.modifier_bindings.get(&modifier) {
return Some(*action);
}
}
}
}
None
}
fn list_bindings(&self) {
println!("\n普通键绑定:");
let mut keys: Vec<_> = self.key_bindings.iter().collect();
keys.sort_by_key(|(key, _)| key.as_str());
for (key, action) in keys {
println!(" {:15} -> {:?}", key, action);
}
println!("\n修饰键绑定:");
let mut modifiers: Vec<_> = self.modifier_bindings.iter().collect();
modifiers.sort_by_key(|(modifier, _)| modifier.as_str());
for (modifier, action) in modifiers {
println!(" {:15} -> {:?}", modifier, action);
}
}
fn handle_combo_event(
&self,
modifier_vks: &[usize],
key_vk: usize,
) -> Option<(Vec<Modifier>, GameAction)> {
let modifiers: Vec<Modifier> = modifier_vks
.iter()
.filter_map(|&code| {
if let Some(KeyboardInput::Modifier(modifier)) =
KeyboardInput::from_code(code, self.platform)
{
Some(modifier)
} else {
None
}
})
.collect();
if let Some(KeyboardInput::Key(key)) = KeyboardInput::from_code(key_vk, self.platform) {
if let Some(action) = self.key_bindings.get(&key) {
return Some((modifiers, *action));
}
}
None
}
}
fn main() {
println!("=== 游戏输入系统示例 ===\n");
let platform = current_platform();
println!("当前平台: {}", platform);
let input_mapper = GameInputMapper::new(platform);
input_mapper.list_bindings();
println!("\n模拟按键事件 (Windows VK 代码):");
let test_keys = [
(0x57, "W"), (0x41, "A"), (0x20, "Space"), (0x31, "1"), (0x10, "Shift"), (0x11, "Ctrl"), ];
for &(vk_code, desc) in &test_keys {
if let Some(action) = input_mapper.handle_key_event(vk_code) {
println!(" VK {:02X} ({:6}) -> {:?}", vk_code, desc, action);
} else {
println!(" VK {:02X} ({:6}) -> 无绑定", vk_code, desc);
}
}
println!("\n模拟组合键事件:");
let combo_tests = [
(vec![0x10], 0x57, "Shift + W"), (vec![0x11], 0x41, "Ctrl + A"), ];
for (modifiers, key, desc) in combo_tests {
if let Some((active_modifiers, action)) = input_mapper.handle_combo_event(&modifiers, key) {
let mod_names: Vec<String> = active_modifiers.iter().map(|m| m.to_string()).collect();
println!(" {} -> {:?} (修饰键: {:?})", desc, action, mod_names);
} else {
println!(" {} -> 无绑定", desc);
}
}
println!("\n示例完成!");
}