diff --git a/Cargo.toml b/Cargo.toml index 093afac..7b196ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,5 @@ bevy = { version = "0.6" } bevy_ecs_tilemap = "0.5" bevy_egui = "0.11" bevy_rapier2d = "0.12" -anyhow = "1.0" \ No newline at end of file +anyhow = "1.0" +leafwing-input-manager = "0.2" diff --git a/assets/asset-licenses.csv b/assets/asset-licenses.csv index 00da1ef..339556d 100644 --- a/assets/asset-licenses.csv +++ b/assets/asset-licenses.csv @@ -1 +1,2 @@ Asset Name,License,Author,Link +images/player.png,Unknown,clipartstation.com,https://clipartstation.com/human-figure-clipart-4/ \ No newline at end of file diff --git a/assets/images/player.png b/assets/images/player.png new file mode 100644 index 0000000..1c7a06b Binary files /dev/null and b/assets/images/player.png differ diff --git a/src/main.rs b/src/main.rs index 65ecb14..7f1bea4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}; use bevy::prelude::*; use bevy::window::WindowMode; use bevy_egui::EguiPlugin; +use leafwing_input_manager::plugin::InputManagerPlugin; mod menus; mod singleplayer; @@ -35,8 +36,10 @@ fn main() { .add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_plugin(EguiPlugin) .add_plugin(menus::MainMenuScene) + // This plugin maps inputs to an input-type agnostic action-state + // We need to provide it with an enum which stores the possible actions a player could take + .add_plugin(InputManagerPlugin::::default()) .add_plugin(singleplayer::SinglePlayerScene) .add_state(GameState::MainMenu) .run(); } - diff --git a/src/menus/common.rs b/src/menus/common.rs index 8ab366b..076bdef 100644 --- a/src/menus/common.rs +++ b/src/menus/common.rs @@ -1,5 +1,6 @@ use bevy::prelude::*; +/// Marks a UI element as disabled. #[derive(Component)] pub struct Disabled; @@ -7,6 +8,7 @@ pub const NORMAL_COLOR: UiColor = UiColor(Color::rgb(0.15, 0.15, 0.15)); pub const HOVERED_COLOR: UiColor = UiColor(Color::rgb(0.25, 0.25, 0.25)); pub const PRESSED_COLOR: UiColor = UiColor(Color::rgb(0.35, 0.75, 0.35)); +/// Creates the [`Style`]s that we add to most buttons. pub fn button_style() -> Style { Style { size: Size::new(Val::Px(150.0), Val::Px(35.0)), @@ -17,6 +19,7 @@ pub fn button_style() -> Style { } } +/// Creates the [`Style`]s that we add to most text. pub fn text_style() -> Style { Style { align_self: AlignSelf::Center, @@ -26,6 +29,7 @@ pub fn text_style() -> Style { } } +/// Creates the [`TextStyle`]s that we add to most text. pub fn text_textstyle(asset_server: &AssetServer) -> TextStyle { TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), @@ -42,6 +46,7 @@ pub fn text_textstyle_disabled(asset_server: &AssetServer) -> TextStyle { } } +/// Creates the [`TextAlignment`]s that we add to most buttons. pub fn button_text_alignment() -> TextAlignment { TextAlignment { horizontal: HorizontalAlign::Center, diff --git a/src/singleplayer/mod.rs b/src/singleplayer/mod.rs index 2019f97..a079b98 100644 --- a/src/singleplayer/mod.rs +++ b/src/singleplayer/mod.rs @@ -1,6 +1,7 @@ use bevy::prelude::*; use bevy_ecs_tilemap::prelude::*; +pub mod player; use crate::GameState; pub struct SinglePlayerScene; @@ -10,7 +11,12 @@ impl Plugin for SinglePlayerScene { app.add_plugin(TilemapPlugin) .add_system(crate::utils::set_texture_filters_to_nearest) .add_system_set( - SystemSet::on_enter(GameState::Playing).with_system(singleplayer_setup), + SystemSet::on_enter(GameState::Playing) + .with_system(singleplayer_setup.label("2d_map_setup")) + .with_system(player::setup_player.after("2d_map_setup")), + ) + .add_system_set( + SystemSet::on_update(GameState::Playing).with_system(player::player_movement), ); } } diff --git a/src/singleplayer/player.rs b/src/singleplayer/player.rs new file mode 100644 index 0000000..cd7946b --- /dev/null +++ b/src/singleplayer/player.rs @@ -0,0 +1,115 @@ +use bevy::{math::const_vec2, prelude::*}; +use leafwing_input_manager::prelude::*; +use std::ops::{Add, Not}; + +pub fn setup_player(mut commands: Commands, asset_server: Res) { + commands + .spawn_bundle(SpriteBundle { + texture: asset_server.load("images/player.png"), + transform: Transform::from_xyz(0., 0., 0.), + sprite: Sprite { + custom_size: Some(Vec2::new(32.0, 64.0)), + ..Default::default() + }, + ..Default::default() + }) + .insert(Player) + .insert(MovementDirection::NotMoving) + .insert_bundle(InputManagerBundle:: { + // Stores "which virtual action buttons are currently pressed" + action_state: ActionState::default(), + // Stores how those actions relate to inputs from your player + input_map: InputMap::new([ + (Action::MoveLeft, KeyCode::A), + (Action::MoveRight, KeyCode::D), + ]), + }); +} + +pub fn player_movement( + time: Res