Skip to content

Commit

Permalink
✨ camera / dead zone
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienjuif authored Nov 23, 2023
1 parent 3261d0b commit 90d1f0c
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 11 deletions.
106 changes: 96 additions & 10 deletions camera/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
use bevy::prelude::{
App, Bundle, Camera2dBundle, Component, Entity, Plugin, PostUpdate, Query, Transform, With,
Without,
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)]
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)
dead_zone: Vec2,
}

impl Camera {
pub fn new(target: Entity, dead_zone: Vec2) -> Self {
Self { target, dead_zone }
}

pub fn new_default(target: Entity) -> Self {
Self {
target,
dead_zone: Vec2::new(100.0, 80.0),
}
}
}

#[derive(Bundle)]
pub struct CameraBundle {
Expand All @@ -18,14 +41,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(),
}
}
Expand All @@ -35,27 +58,90 @@ 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 cameraman(
fn center(
mut query_camera: Query<(&mut Transform, &Camera), Without<Target>>,
query_targets: Query<(&Transform, Entity), With<Target>>,
) {
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 {
if camera.target == target_entity {
camera_transform.translation.x = target_transform.translation.x;
camera_transform.translation.y = target_transform.translation.y;
break;
}
}
}
}

fn cameraman(
mut query_camera: Query<(&mut Transform, &Camera), Without<Target>>,
query_targets: Query<(&Transform, Entity), With<Target>>,
) {
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 {
let diff = camera_transform.translation - target_transform.translation;
let diff_abs = diff.abs();

if diff_abs.x > camera.dead_zone.x {
camera_transform.translation.x = target_transform.translation.x
- if diff.x > 0. {
-camera.dead_zone.x
} else {
camera.dead_zone.x
};
}
if diff_abs.y > camera.dead_zone.y {
camera_transform.translation.y = target_transform.translation.y
- if diff.y > 0. {
-camera.dead_zone.y
} else {
camera.dead_zone.y
};
}

break;
}
}
}
}

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<GizmoConfig>,
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.dead_zone * 2.0,
Color::RED,
);
}
}
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +38,11 @@ fn main() {
CastlesPlugin,
HealthPlugin,
LocalPlayerPlugin,
))
// --- camera ---
.add_plugins((
CameraPlugin,
CameraDebugPlugin,
))
// --- physics ---
.add_plugins((
Expand Down

0 comments on commit 90d1f0c

Please sign in to comment.