use bevy::prelude::*; use bevy_ecs_ldtk::prelude::*; use bevy_rapier2d::dynamics::Velocity; use crate::{colliders::ColliderBundle, ground_detection::GroundDetection}; pub struct PlayerPlugin; impl Plugin for PlayerPlugin { fn build(&self, app: &mut App) { app.add_systems(Update, player_movement) .register_ldtk_entity::("Player"); } } #[derive(Default, Component)] enum Facing { Left, #[default] Right, } #[derive(Default, Component, LdtkEntity)] pub(crate) struct Player { direction: Facing, } #[derive(Default, Bundle, LdtkEntity)] struct PlayerBundle { player: Player, #[sprite_sheet_bundle] sprite_bundle: LdtkSpriteSheetBundle, #[grid_coords] grid_coords: GridCoords, pub ground_detection: GroundDetection, #[from_entity_instance] pub collider_bundle: ColliderBundle, } fn player_movement( mut query: Query<(&mut Velocity, &GroundDetection, &mut Player, &mut Sprite), With>, input: Res>, ) { // let movement_direction = // if input.just_pressed(KeyCode::KeyW) || input.just_pressed(KeyCode::Space) { // GridCoords::new(0, 1) // } else if input.just_pressed(KeyCode::KeyA) { // GridCoords::new(-1, 0) // } else if input.just_pressed(KeyCode::KeyS) { // GridCoords::new(0, -1) // } else if input.just_pressed(KeyCode::KeyD) { // GridCoords::new(1, 0) // } else { // return; // }; for (mut velocity, ground_detection, mut player, mut p_sprite) in &mut query { let right = if input.pressed(KeyCode::KeyD) { player.direction = Facing::Right; 1. } else { 0. }; let left = if input.pressed(KeyCode::KeyA) { player.direction = Facing::Left; 1. } else { 0. }; match player.direction { Facing::Right => {p_sprite.flip_x = false;}, Facing::Left => {p_sprite.flip_x = true;}, } // gotta query for sprite to control how the player "appears" to look in either direction velocity.linvel.x = (right - left) * 200.; if input.just_pressed(KeyCode::Space) && ground_detection.on_ground { velocity.linvel.y = 500.; } } // for mut player_grid_coords in players.iter_mut() { // let destination = *player_grid_coords + movement_direction; // if !level_walls.in_wall(&destination) { // *player_grid_coords = destination; // } // } } // #[derive(Default, Resource)] // struct LevelWalls { // wall_locations: HashSet, // level_width: i32, // level_height: i32, // } // impl LevelWalls { // fn in_wall(&self, grid_coords: &GridCoords) -> bool { // grid_coords.x < 0 // || grid_coords.y < 0 // || grid_coords.x >= self.level_width // || grid_coords.y >= self.level_height // || self.wall_locations.contains(grid_coords) // } // } // fn cache_wall_locations( // mut level_walls: ResMut, // mut level_events: EventReader, // walls: Query<&GridCoords, With>, // ldtk_project_entities: Query<&Handle>, // ldtk_project_assets: Res>, // ) { // for level_event in level_events.read() { // if let LevelEvent::Spawned(level_iid) = level_event { // let ldtk_project = ldtk_project_assets // .get(ldtk_project_entities.single()) // .expect("LdtkProject should be loaded when level is spawned"); // let level = ldtk_project // .get_raw_level_by_iid(level_iid.get()) // .expect("spawned level should exist in project"); // let wall_locations = walls.iter().copied().collect(); // let new_level_walls = LevelWalls { // wall_locations, // level_width: level.px_wid / crate::GRID_SIZE, // level_height: level.px_hei / crate::GRID_SIZE, // }; // *level_walls = new_level_walls; // } // } // }