From 7013490e596dc06ec32f92358ca28cddf772c8a3 Mon Sep 17 00:00:00 2001 From: eri Date: Sat, 13 Jul 2024 20:10:50 +0200 Subject: [PATCH] feat: basic touch input --- Cargo.toml | 4 +++- examples/jump.rs | 2 +- src/input.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9b39bed..6276592 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,9 @@ release = [ # Only in release (build with --release --no-default-features --feat "bevy_embedded_assets", "common", "tts", + "touch", ] -common = ["input", "menu", "ui", "persist"] +common = ["input", "menu", "persist", "ui"] 3d_camera = [] input = ["leafwing-input-manager"] @@ -35,6 +36,7 @@ navigation = ["bevy-alt-ui-navigation-lite"] persist = ["bevy-persistent"] pixel_perfect = [] resizable = [] +touch = ["input"] trace = ["release", "bevy/trace_tracy"] ui = ["sickle_ui"] diff --git a/examples/jump.rs b/examples/jump.rs index 0a7585c..0640087 100644 --- a/examples/jump.rs +++ b/examples/jump.rs @@ -203,7 +203,7 @@ fn update_player( }; // Move - let axis = input.axis_pair(&Action::Move); + let axis = input.clamped_axis_pair(&Action::Move); let dir = axis.unwrap_or_default().x(); if dir.abs() > 0. { player.velocity.x = dir * MOVE_VEL; diff --git a/src/input.rs b/src/input.rs index 3ca9321..af89446 100644 --- a/src/input.rs +++ b/src/input.rs @@ -23,6 +23,15 @@ impl Plugin for InputPlugin { Update, handle_input.run_if(in_state(crate::GameState::Play)), ); + + #[cfg(feature = "touch")] + app.add_systems( + PreUpdate, + touch_system + .chain() + .after(bevy::input::InputSystem) + .before(leafwing_input_manager::plugin::InputManagerSystem::Update), + ); } } @@ -52,11 +61,16 @@ fn init(mut cmd: Commands) { input_map .insert(Action::Jump, KeyCode::Space) .insert(Action::Jump, GamepadButtonType::South) + .insert(Action::Jump, MouseButton::Left) .insert(Action::Move, KeyboardVirtualDPad::WASD) .insert(Action::Move, GamepadStick::LEFT) .insert(Action::Pause, KeyCode::Escape) .insert(Action::Pause, GamepadButtonType::Start); + // If touch input is enabled, make the touch movement map to the move action + #[cfg(feature = "touch")] + input_map.insert(Action::Move, MouseMove::default()); + cmd.spawn(InputManagerBundle::with_map(input_map)); } @@ -74,3 +88,44 @@ fn handle_input( next_state.set(crate::GameState::Menu) } } + +/// Touch inputs are converted to equivalent mouse values to make them +/// compatible with leafwing +#[cfg(feature = "touch")] +fn touch_system( + window: Query>, + touches: Res, + mut mouse_button_writer: EventWriter, + mut cursor_moved_writer: EventWriter, +) { + use bevy::input::{mouse::MouseButtonInput, ButtonState}; + + let Ok(window) = window.get_single() else { return }; + + for _ in touches.iter_just_pressed() { + mouse_button_writer.send(MouseButtonInput { + button: MouseButton::Left, + state: ButtonState::Pressed, + window, + }); + } + + for _ in touches.iter_just_released() { + mouse_button_writer.send(MouseButtonInput { + button: MouseButton::Left, + state: ButtonState::Released, + window, + }); + } + + // Doesn't support multitouch + let Some(touch) = touches.iter().next() else { + return; + }; + + cursor_moved_writer.send(CursorMoved { + position: touch.position(), + delta: Some(touch.delta()), + window, + }); +}