#![allow(
clippy::needless_pass_by_value,
clippy::explicit_iter_loop,
clippy::uninlined_format_args
)]
use bevy::prelude::*;
use bevy::text::LetterSpacing;
use bevy_archie::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ControllerPlugin::default())
.add_systems(Startup, setup)
.add_systems(Update, (display_input_state, handle_actions))
.run();
}
#[derive(Component)]
struct InputStateText;
#[derive(Component)]
struct ActionText;
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
commands
.spawn((
Node {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
flex_direction: FlexDirection::Column,
padding: UiRect::all(Val::Px(20.0)),
row_gap: Val::Px(10.0),
..default()
},
BackgroundColor(Color::srgb(0.1, 0.1, 0.15)),
))
.with_children(|parent| {
parent.spawn((
Text::new("Bevy Archie - Controller Support Demo"),
TextFont {
font: FontSource::SansSerif,
font_size: FontSize::Px(32.0),
weight: FontWeight::BOLD,
..default()
},
TextColor(Color::WHITE),
LetterSpacing::Px(1.0),
));
parent.spawn((
Text::new("Input Device: Mouse"),
TextFont {
font: FontSource::SansSerif,
font_size: FontSize::Px(24.0),
..default()
},
TextColor(Color::srgb(0.7, 0.7, 0.7)),
InputStateText,
));
parent.spawn((
Text::new("Actions: None"),
TextFont {
font: FontSource::SansSerif,
font_size: FontSize::Px(20.0),
..default()
},
TextColor(Color::srgb(0.5, 0.8, 0.5)),
ActionText,
));
parent.spawn((
Text::new(
"Instructions:\n\
- Use keyboard, mouse, or gamepad\n\
- The active input device will be detected automatically\n\
- Press buttons to see action states",
),
TextFont {
font: FontSource::SansSerif,
font_size: FontSize::Px(18.0),
..default()
},
TextColor(Color::srgb(0.6, 0.6, 0.6)),
));
});
}
fn display_input_state(
input_state: Res<InputDeviceState>,
config: Res<ControllerConfig>,
mut query: Query<&mut Text, With<InputStateText>>,
) {
if !input_state.is_changed() {
return;
}
for mut text in query.iter_mut() {
let device_name = match input_state.active_device {
InputDevice::Mouse => "Mouse".to_string(),
InputDevice::Keyboard => "Keyboard".to_string(),
InputDevice::Gamepad(_) => {
format!("Gamepad ({:?})", config.layout())
}
};
let gamepads_connected = input_state.connected_gamepads.len();
**text = format!(
"Input Device: {}\nConnected Gamepads: {}",
device_name, gamepads_connected
);
}
}
fn handle_actions(actions: Res<ActionState>, mut query: Query<&mut Text, With<ActionText>>) {
let mut active_actions = Vec::new();
for action in GameAction::all() {
if actions.pressed(*action) {
active_actions.push(format!("{:?}", action));
}
}
for mut text in query.iter_mut() {
if active_actions.is_empty() {
**text = "Actions: None".to_string();
} else {
**text = format!("Actions: {}", active_actions.join(", "));
}
}
}