bevy-learning

A learning project of mine.
git clone git://archive.git.mtrnord.blog/MTRNord/bevy-learning.git
Log | Files | Refs

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(&current_loc) {
    173             tmp_to_move.push(*movable);
    174             current_loc = current_loc + delta;
    175         }
    176         if let Some(_immovable) = immovables.get(&current_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 }