use bevy::prelude::*;
use leafwing_input_manager::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(InputManagerPlugin::<ArpgAction>::default())
.add_systems(Startup, spawn_player)
.add_systems(Update, cast_fireball)
.add_systems(Update, player_dash)
.add_message::<PlayerWalk>()
.add_systems(Update, player_walks)
.run();
}
#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)]
enum ArpgAction {
Up,
Down,
Left,
Right,
Ability1,
Ability2,
Ability3,
Ability4,
Ultimate,
}
impl ArpgAction {
const DIRECTIONS: [Self; 4] = [
ArpgAction::Up,
ArpgAction::Down,
ArpgAction::Left,
ArpgAction::Right,
];
fn direction(self) -> Option<Dir2> {
match self {
ArpgAction::Up => Some(Dir2::Y),
ArpgAction::Down => Some(Dir2::NEG_Y),
ArpgAction::Left => Some(Dir2::NEG_X),
ArpgAction::Right => Some(Dir2::X),
_ => None,
}
}
}
#[derive(Component)]
pub struct Player;
impl Player {
fn default_input_map() -> InputMap<ArpgAction> {
use ArpgAction::*;
let mut input_map = InputMap::default();
input_map.insert(Up, KeyCode::ArrowUp);
input_map.insert(Up, GamepadButton::DPadUp);
input_map.insert(Down, KeyCode::ArrowDown);
input_map.insert(Down, GamepadButton::DPadDown);
input_map.insert(Left, KeyCode::ArrowLeft);
input_map.insert(Left, GamepadButton::DPadLeft);
input_map.insert(Right, KeyCode::ArrowRight);
input_map.insert(Right, GamepadButton::DPadRight);
input_map.insert(Ability1, KeyCode::KeyQ);
input_map.insert(Ability1, GamepadButton::West);
input_map.insert(Ability1, MouseButton::Left);
input_map.insert(Ability2, KeyCode::KeyW);
input_map.insert(Ability2, GamepadButton::North);
input_map.insert(Ability2, MouseButton::Right);
input_map.insert(Ability3, KeyCode::KeyE);
input_map.insert(Ability3, GamepadButton::East);
input_map.insert(Ability4, KeyCode::Space);
input_map.insert(Ability4, GamepadButton::South);
input_map.insert(Ultimate, KeyCode::KeyR);
input_map.insert(Ultimate, GamepadButton::LeftTrigger2);
input_map
}
}
fn spawn_player(mut commands: Commands) {
commands.spawn((Player, Player::default_input_map()));
}
fn cast_fireball(action_state: Single<&ActionState<ArpgAction>, With<Player>>) {
if action_state.just_pressed(&ArpgAction::Ability1) {
println!("Fwoosh!");
}
}
fn player_dash(action_state: Single<&ActionState<ArpgAction>, With<Player>>) {
if action_state.just_pressed(&ArpgAction::Ability4) {
let mut direction_vector = Vec2::ZERO;
for input_direction in ArpgAction::DIRECTIONS {
if action_state.pressed(&input_direction) {
if let Some(direction) = input_direction.direction() {
direction_vector += *direction;
}
}
}
let net_direction = Dir2::new(direction_vector);
if let Ok(direction) = net_direction {
println!("Dashing in {direction:?}");
}
}
}
#[derive(Message)]
pub struct PlayerWalk {
pub direction: Dir2,
}
fn player_walks(
action_state: Single<&ActionState<ArpgAction>, With<Player>>,
mut message_writer: MessageWriter<PlayerWalk>,
) {
let mut direction_vector = Vec2::ZERO;
for input_direction in ArpgAction::DIRECTIONS {
if action_state.pressed(&input_direction) {
if let Some(direction) = input_direction.direction() {
direction_vector += *direction;
}
}
}
let net_direction = Dir2::new(direction_vector);
if let Ok(direction) = net_direction {
message_writer.write(PlayerWalk { direction });
}
}