use bevy::{platform::collections::HashMap, prelude::*};
use leafwing_input_manager::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(InputManagerPlugin::<Action>::default())
.init_resource::<JoinedPlayers>()
.add_systems(Update, (join, jump, disconnect))
.run();
}
#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)]
enum Action {
Jump,
Disconnect,
}
#[derive(Resource, Default)]
struct JoinedPlayers(pub HashMap<Entity, Entity>);
#[derive(Component)]
struct Player {
gamepad: Entity,
}
fn join(
mut commands: Commands,
mut joined_players: ResMut<JoinedPlayers>,
gamepads: Query<(Entity, &Gamepad)>,
) {
for (gamepad_entity, gamepad) in gamepads.iter() {
if gamepad.pressed(GamepadButton::LeftTrigger)
&& gamepad.pressed(GamepadButton::RightTrigger)
{
if !joined_players.0.contains_key(&gamepad_entity) {
println!("Player {gamepad_entity} has joined the game!");
let input_map = InputMap::new([
(Action::Jump, GamepadButton::South),
(Action::Disconnect, GamepadButton::Select),
])
.with_gamepad(gamepad_entity);
let player = commands
.spawn(input_map)
.insert(Player {
gamepad: gamepad_entity,
})
.id();
unsafe {
joined_players
.0
.insert_unique_unchecked(gamepad_entity, player);
}
}
}
}
}
fn jump(action_query: Query<(&ActionState<Action>, &Player)>) {
for (action_state, player) in action_query.iter() {
if action_state.just_pressed(&Action::Jump) {
println!("Player {} jumped!", player.gamepad);
}
}
}
fn disconnect(
mut commands: Commands,
action_query: Query<(&ActionState<Action>, &Player)>,
mut joined_players: ResMut<JoinedPlayers>,
) {
for (action_state, player) in action_query.iter() {
if action_state.pressed(&Action::Disconnect) {
let player_entity = *joined_players.0.get(&player.gamepad).unwrap();
commands.entity(player_entity).despawn();
joined_players.0.remove(&player.gamepad);
println!("Player {} has disconnected!", player.gamepad);
}
}
}