From 445d6353fc2c7648abf5de87e45f48ac6da03e53 Mon Sep 17 00:00:00 2001 From: Fabien JUIF Date: Thu, 23 Nov 2023 11:58:48 +0100 Subject: [PATCH 1/4] :sparkles: camera / offset --- camera/src/lib.rs | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/camera/src/lib.rs b/camera/src/lib.rs index 5507a7d..ddcacd9 100644 --- a/camera/src/lib.rs +++ b/camera/src/lib.rs @@ -1,13 +1,32 @@ -use bevy::prelude::{ - App, Bundle, Camera2dBundle, Component, Entity, Plugin, PostUpdate, Query, Transform, With, - Without, +use bevy::{ + math::Vec2, + prelude::{ + App, Bundle, Camera2dBundle, Component, Entity, Plugin, PostUpdate, Query, Transform, With, + Without, + }, }; #[derive(Component)] pub struct Target; #[derive(Component)] -pub struct Camera(pub Entity); +pub struct Camera { + target: Entity, // TODO: find a way to have multiple targets per camera, but also being able to have multi cameras (n-n) + offset: Vec2, +} + +impl Camera { + pub fn new(target: Entity, offset: Vec2) -> Self { + Self { target, offset } + } + + pub fn new_default(target: Entity) -> Self { + Self { + target, + offset: Vec2::new(100.0, 80.0), + } + } +} #[derive(Bundle)] pub struct CameraBundle { @@ -18,14 +37,14 @@ pub struct CameraBundle { impl CameraBundle { pub fn new(target: Entity, bundle: Camera2dBundle) -> Self { Self { - camera: Camera(target), + camera: Camera::new_default(target), bundle, } } pub fn new_with_default_bundle(target: Entity) -> Self { Self { - camera: Camera(target), + camera: Camera::new_default(target), bundle: Camera2dBundle::default(), } } @@ -45,14 +64,21 @@ fn cameraman( ) { for (mut camera_transform, camera) in &mut query_camera { for (target_transform, target_entity) in &query_targets { - if camera.0 != target_entity { + if camera.target != target_entity { continue; } // TODO: for now we follow the first target but we could think of doing an average positions of all the targets - if camera.0 == target_entity { - camera_transform.translation.x = target_transform.translation.x; - camera_transform.translation.y = target_transform.translation.y; + if camera.target == target_entity { + let diff = camera_transform.translation - target_transform.translation; + let diff = diff.abs(); + + if diff.x > camera.offset.x { + camera_transform.translation.x = target_transform.translation.x; + } + if diff.y > camera.offset.y { + camera_transform.translation.y = target_transform.translation.y; + } break; } From 2608bfe0ec03f23dce77b81faa77380592510262 Mon Sep 17 00:00:00 2001 From: Fabien JUIF Date: Thu, 23 Nov 2023 12:15:45 +0100 Subject: [PATCH 2/4] offset --- camera/src/lib.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/camera/src/lib.rs b/camera/src/lib.rs index ddcacd9..fe72820 100644 --- a/camera/src/lib.rs +++ b/camera/src/lib.rs @@ -71,13 +71,23 @@ fn cameraman( // TODO: for now we follow the first target but we could think of doing an average positions of all the targets if camera.target == target_entity { let diff = camera_transform.translation - target_transform.translation; - let diff = diff.abs(); + let diff_abs = diff.abs(); - if diff.x > camera.offset.x { - camera_transform.translation.x = target_transform.translation.x; + if diff_abs.x > camera.offset.x { + camera_transform.translation.x = target_transform.translation.x + - if diff.x > 0. { + -camera.offset.x + } else { + camera.offset.x + }; } - if diff.y > camera.offset.y { - camera_transform.translation.y = target_transform.translation.y; + if diff_abs.y > camera.offset.y { + camera_transform.translation.y = target_transform.translation.y + - if diff.y > 0. { + -camera.offset.y + } else { + camera.offset.y + }; } break; From 1d139900e26ee46c8ff70ca9aa71c8bb8938790b Mon Sep 17 00:00:00 2001 From: Fabien JUIF Date: Thu, 23 Nov 2023 12:30:17 +0100 Subject: [PATCH 3/4] offset --- camera/src/lib.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 6 +++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/camera/src/lib.rs b/camera/src/lib.rs index fe72820..5b48a88 100644 --- a/camera/src/lib.rs +++ b/camera/src/lib.rs @@ -1,9 +1,13 @@ use bevy::{ + app::{PostStartup, Update}, + ecs::system::ResMut, + gizmos::{gizmos::Gizmos, GizmoConfig}, math::Vec2, prelude::{ App, Bundle, Camera2dBundle, Component, Entity, Plugin, PostUpdate, Query, Transform, With, Without, }, + render::color::Color, }; #[derive(Component)] @@ -54,7 +58,28 @@ pub struct CameraPlugin; impl Plugin for CameraPlugin { fn build(&self, app: &mut App) { - app.add_systems(PostUpdate, cameraman); + app.add_systems(PostStartup, center) + .add_systems(PostUpdate, cameraman); + } +} + +fn center( + mut query_camera: Query<(&mut Transform, &Camera), Without>, + query_targets: Query<(&Transform, Entity), With>, +) { + for (mut camera_transform, camera) in &mut query_camera { + for (target_transform, target_entity) in &query_targets { + if camera.target != target_entity { + continue; + } + + // TODO: for now we follow the first target but we could think of doing an average positions of all the targets + if camera.target == target_entity { + camera_transform.translation.x = target_transform.translation.x; + camera_transform.translation.y = target_transform.translation.y; + break; + } + } } } @@ -95,3 +120,28 @@ fn cameraman( } } } + +pub struct CameraDebugPlugin; + +impl Plugin for CameraDebugPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, debug); + } +} + +fn debug( + mut gizmos: Gizmos, + mut config: ResMut, + query_cameras: Query<(&Transform, &Camera)>, +) { + config.line_width = 1.0; + + for (camera_transform, camera) in &query_cameras { + gizmos.rect_2d( + camera_transform.translation.truncate(), + 0., + camera.offset * 2.0, + Color::RED, + ); + } +} diff --git a/src/main.rs b/src/main.rs index 06c8925..5bb466e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use bevy::{ prelude::*, DefaultPlugins, }; -use bevy_camera::CameraPlugin; +use bevy_camera::{CameraDebugPlugin, CameraPlugin}; use bevy_rapier2d::prelude::*; use castles::CastlesPlugin; use health::HealthPlugin; @@ -38,7 +38,11 @@ fn main() { CastlesPlugin, HealthPlugin, LocalPlayerPlugin, + )) + // --- camera --- + .add_plugins(( CameraPlugin, + CameraDebugPlugin, )) // --- physics --- .add_plugins(( From 449a7824639f19897194c3f135cf443e44e6b993 Mon Sep 17 00:00:00 2001 From: Fabien JUIF Date: Thu, 23 Nov 2023 12:32:38 +0100 Subject: [PATCH 4/4] wording --- camera/src/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/camera/src/lib.rs b/camera/src/lib.rs index 5b48a88..5118336 100644 --- a/camera/src/lib.rs +++ b/camera/src/lib.rs @@ -16,18 +16,18 @@ pub struct Target; #[derive(Component)] pub struct Camera { target: Entity, // TODO: find a way to have multiple targets per camera, but also being able to have multi cameras (n-n) - offset: Vec2, + dead_zone: Vec2, } impl Camera { - pub fn new(target: Entity, offset: Vec2) -> Self { - Self { target, offset } + pub fn new(target: Entity, dead_zone: Vec2) -> Self { + Self { target, dead_zone } } pub fn new_default(target: Entity) -> Self { Self { target, - offset: Vec2::new(100.0, 80.0), + dead_zone: Vec2::new(100.0, 80.0), } } } @@ -98,20 +98,20 @@ fn cameraman( let diff = camera_transform.translation - target_transform.translation; let diff_abs = diff.abs(); - if diff_abs.x > camera.offset.x { + if diff_abs.x > camera.dead_zone.x { camera_transform.translation.x = target_transform.translation.x - if diff.x > 0. { - -camera.offset.x + -camera.dead_zone.x } else { - camera.offset.x + camera.dead_zone.x }; } - if diff_abs.y > camera.offset.y { + if diff_abs.y > camera.dead_zone.y { camera_transform.translation.y = target_transform.translation.y - if diff.y > 0. { - -camera.offset.y + -camera.dead_zone.y } else { - camera.offset.y + camera.dead_zone.y }; } @@ -140,7 +140,7 @@ fn debug( gizmos.rect_2d( camera_transform.translation.truncate(), 0., - camera.offset * 2.0, + camera.dead_zone * 2.0, Color::RED, ); }