player.rs (5847B)
1 use crate::entities::common::Health; 2 use crate::entities::markers::{Movable, Player, Wall}; 3 use crate::entities::player::{PlayerBundle, PlayerName, PlayerXp}; 4 use crate::plugins::world::{GridLocation, MainCamera, SPRITE_HEIGHT, SPRITE_WIDTH}; 5 use crate::{AssetsLoading, GameState}; 6 use bevy::asset::LoadState; 7 use bevy::prelude::*; 8 use std::collections::HashMap; 9 10 pub const PLAYER_START: GridLocation = GridLocation(2, -2); 11 12 pub struct PlayerPlugin; 13 14 impl Plugin for PlayerPlugin { 15 fn build(&self, app: &mut AppBuilder) { 16 app.add_system(player_movement.system()) 17 .add_system(setup_player.system()); 18 } 19 } 20 21 fn setup_player( 22 mut commands: Commands, 23 asset_server: Res<AssetServer>, 24 texture_atlases: ResMut<Assets<TextureAtlas>>, 25 game_state: ResMut<GameState>, 26 loading: Res<AssetsLoading>, 27 textures: Res<Assets<Texture>>, 28 ) { 29 if !game_state.spawned { 30 let mut ready = true; 31 for handle in loading.0.iter() { 32 match asset_server.get_load_state(handle) { 33 LoadState::Failed => { 34 ready = false; 35 } 36 LoadState::Loaded => {} 37 _ => { 38 ready = false; 39 } 40 } 41 } 42 43 if !ready { 44 return; 45 } 46 47 setup_player_internal( 48 PLAYER_START, 49 &mut commands, 50 texture_atlases, 51 game_state, 52 &textures, 53 ); 54 } 55 } 56 57 fn setup_player_internal( 58 grid_location: GridLocation, 59 commands: &mut Commands, 60 mut texture_atlases: ResMut<Assets<TextureAtlas>>, 61 mut game_state: ResMut<GameState>, 62 textures: &Res<Assets<Texture>>, 63 ) { 64 let texture_handle = game_state.asset_map.get("DungeonTileset").unwrap(); 65 let texture: &Texture = textures.get(texture_handle.id).unwrap(); 66 let cols = texture.size.width / 16; 67 let rows = texture.size.height / 16; 68 let texture_atlas = TextureAtlas::from_grid( 69 texture_handle.clone(), 70 Vec2::new(16.0, 16.0), 71 cols as usize, 72 rows as usize, 73 ); 74 let texture_atlas_handle = texture_atlases.add(texture_atlas); 75 76 // Spawn player 77 commands 78 .spawn_bundle(SpriteSheetBundle { 79 sprite: TextureAtlasSprite { 80 index: 362, 81 ..Default::default() 82 }, 83 transform: Transform::from_translation(Vec3::new( 84 SPRITE_WIDTH * grid_location.0 as f32, 85 SPRITE_HEIGHT * grid_location.1 as f32, 86 0.0, 87 )), 88 texture_atlas: texture_atlas_handle, 89 ..Default::default() 90 }) 91 .insert(grid_location) 92 .insert(Movable) 93 .insert(PlayerBundle { 94 xp: PlayerXp(0.0), 95 name: PlayerName("Player 1".into()), 96 health: Health { hp: 100.0 }, 97 _p: Player, 98 }); 99 game_state.spawned = true; 100 } 101 102 #[allow(clippy::type_complexity)] 103 fn player_movement( 104 keyboard_input: Res<Input<KeyCode>>, 105 mut set: QuerySet<( 106 Query<(Entity, &Movable, &mut GridLocation)>, 107 Query<(Entity, &Player, &GridLocation)>, 108 Query<(Entity, &Wall, &GridLocation)>, 109 Query<&mut GridLocation, With<MainCamera>>, 110 )>, 111 ) { 112 let _shift = keyboard_input.pressed(KeyCode::LShift) || keyboard_input.pressed(KeyCode::RShift); 113 let _ctrl = 114 keyboard_input.pressed(KeyCode::LControl) || keyboard_input.pressed(KeyCode::RControl); 115 116 let delta = { 117 let mut delta = GridLocation(0, 0); 118 if keyboard_input.just_pressed(KeyCode::A) { 119 delta = GridLocation(-1, 0); 120 } 121 if keyboard_input.just_pressed(KeyCode::D) { 122 delta = GridLocation(1, 0); 123 } 124 if keyboard_input.just_pressed(KeyCode::S) { 125 delta = GridLocation(0, -1); 126 } 127 if keyboard_input.just_pressed(KeyCode::W) { 128 delta = GridLocation(0, 1); 129 } 130 if delta == GridLocation(0, 0) { 131 return; 132 } 133 delta 134 }; 135 136 let immovables: HashMap<GridLocation, Entity> = { 137 let mut tmp = HashMap::new(); 138 for (wall_entity, _wall, wall_grid_location) in set.q2_mut().iter_mut() { 139 tmp.insert( 140 GridLocation(wall_grid_location.0, wall_grid_location.1), 141 wall_entity, 142 ); 143 } 144 tmp 145 }; 146 147 let movables: HashMap<GridLocation, Entity> = { 148 let mut tmp = HashMap::new(); 149 for (movable_entity, _movable, grid_location) in set.q0_mut().iter_mut() { 150 tmp.insert( 151 GridLocation(grid_location.0, grid_location.1), 152 movable_entity, 153 ); 154 } 155 tmp 156 }; 157 158 let mut to_move: Vec<Entity> = vec![]; 159 let mut last_pos = None; 160 161 for (_player_entity, _player, player_grid_location) in set.q1().iter() { 162 let mut tmp_to_move = vec![]; 163 164 let mut current_loc = *player_grid_location; 165 //prevent block skips 166 if let Some(pos) = last_pos { 167 if pos == current_loc { 168 continue; 169 } 170 } 171 172 while let Some(movable) = movables.get(¤t_loc) { 173 tmp_to_move.push(*movable); 174 current_loc = current_loc + delta; 175 } 176 if let Some(_immovable) = immovables.get(¤t_loc) { 177 continue; 178 } 179 last_pos = Some(current_loc); 180 to_move.append(&mut tmp_to_move); 181 } 182 183 for loc in to_move { 184 { 185 let mut camera_grid_location = set.q3_mut().iter_mut().next().unwrap(); 186 *camera_grid_location = *camera_grid_location + delta; 187 } 188 189 let mut grid_location: Mut<GridLocation> = set.q0_mut().get_component_mut(loc).unwrap(); 190 *grid_location = *grid_location + delta; 191 } 192 }