From d2281817d0f261fa6ee623932d07b8e1282ed4a0 Mon Sep 17 00:00:00 2001 From: tuxmain Date: Wed, 24 Aug 2022 00:45:57 +0200 Subject: [PATCH] Camera follows selected character --- src/game.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- src/levels.rs | 3 +++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/game.rs b/src/game.rs index 7b170c1..97e61b7 100644 --- a/src/game.rs +++ b/src/game.rs @@ -32,9 +32,14 @@ impl Plugin for GamePlugin { .add_system_set( SystemSet::on_update(AppState::Game) .with_system(crate::levels::post_setup_level) - .with_system(keyboard_input_system), + .with_system(keyboard_input_system) + .with_system(move_camera), + ) + .add_system_set( + SystemSet::on_update(AppState::Win) + .with_system(keyboard_input_system) + .with_system(move_camera), ) - .add_system_set(SystemSet::on_update(AppState::Win).with_system(keyboard_input_system)) .add_system_to_stage(CoreStage::PostUpdate, collision_event_system); } } @@ -88,12 +93,14 @@ fn setup( mut commands: Commands, mut current_level: ResMut, mut level_startup_event: EventWriter, + mut camera_query: Query<&mut Transform, With>, ) { let level_id = LevelId(current_level.0.map_or(0, |level_id| level_id.0 + 1)); crate::levels::setup_level( &mut commands, &mut current_level, &mut level_startup_event, + &mut camera_query, level_id, ); } @@ -343,3 +350,40 @@ fn win_setup(mut commands: Commands, asset_server: Res) { }) .insert(Level); } + +fn move_camera( + mut camera_query: Query<(&Camera, &mut Transform, &GlobalTransform)>, + characters: Query<(&CharacterId, &Transform), Without>, + level_query: Query<&SelectedCharacterId>, +) { + const MARGIN: f32 = 128.0; + + if let Ok(selected_character_id) = level_query.get_single() { + if let Some(selected_character_id) = &selected_character_id.0 { + if let Some((_character_id, transform)) = characters + .iter() + .find(|(character_id, _transform)| *character_id == selected_character_id) + { + let (camera, mut camera_transform, camera_global_transform) = + camera_query.single_mut(); + + let pos = camera + .world_to_viewport(camera_global_transform, transform.translation) + .unwrap(); + let size = camera.logical_viewport_size().unwrap(); + if pos.x < MARGIN { + camera_transform.translation.x += pos.x - MARGIN; + } + if pos.x > size.x - MARGIN { + camera_transform.translation.x += MARGIN + pos.x - size.x; + } + if pos.y < MARGIN { + camera_transform.translation.y += pos.y - MARGIN; + } + if pos.y > size.y - MARGIN { + camera_transform.translation.y += MARGIN + pos.y - size.y; + } + } + } + } +} diff --git a/src/levels.rs b/src/levels.rs index cd15cfe..0e4e653 100644 --- a/src/levels.rs +++ b/src/levels.rs @@ -14,6 +14,7 @@ pub fn setup_level( commands: &mut Commands, current_level: &mut ResMut, level_startup_event: &mut EventWriter, + camera_query: &mut Query<&mut Transform, With>, level_id: LevelId, ) { let level_entity = commands @@ -24,6 +25,8 @@ pub fn setup_level( .id(); current_level.0 = Some(level_id); + camera_query.single_mut().translation = Default::default(); + level_startup_event.send(LevelStartupEvent(level_entity)); }