Skip to main content

reactor_camera/
components.rs

1use bevy::prelude::*;
2use reactor_spatial::prelude::*;
3
4/// Marker component for the main camera
5#[derive(Component, Default, Clone, Copy, PartialEq, Debug, Reflect)]
6pub struct MainCamera;
7
8/// Marker component for the main camera target
9#[derive(Component, Default, Clone, Copy, PartialEq, Debug, Reflect)]
10pub struct MainCameraShouldTarget;
11
12/// Component that specifies a given cameras target
13#[derive(Component, Default, Clone, Copy, PartialEq, Eq, Debug, Reflect)]
14pub struct CameraTarget(pub Option<Entity>);
15
16/// Component that specifies the cameras movement style
17#[derive(Component, Default, Clone, Copy, PartialEq, Debug, Reflect)]
18pub enum CameraStyle {
19    /// Follows the target with a deadzone
20    DeadZone(DeadZone),
21    /// Follows the target with a screen by screen movement
22    ScreenByScreen,
23    #[default]
24    /// Follows the target exactly
25    Exact,
26}
27
28/// Sub-component that specifies the cameras deadzone for `CameraStyle::DeadZone`
29#[derive(Default, Clone, Copy, PartialEq, Debug, Reflect)]
30pub struct DeadZone {
31    /// The deadzone's width
32    pub width: f32,
33    /// The deadzone's height
34    pub height: f32,
35}
36
37impl DeadZone {
38    /// Creates a new deadzone
39    pub fn new(width: f32, height: f32) -> Self {
40        Self { width, height }
41    }
42
43    /// Returns the deadzone's half width
44    pub fn half_width(&self) -> f32 {
45        self.width / 2.
46    }
47
48    /// Returns the deadzone's half height
49    pub fn half_height(&self) -> f32 {
50        self.height / 2.
51    }
52}
53
54/// Component that specifies the cameras lerp factor
55#[derive(Component, Clone, Copy, PartialEq, Debug, Reflect)]
56pub struct CameraLerp {
57    /// The lerp factor, higher is faster
58    pub factor: Vec2,
59}
60
61impl CameraLerp {
62    /// Creates a new lerp
63    pub fn new(factor: f32) -> Self {
64        Self {
65            factor: Vec2::new(factor, factor),
66        }
67    }
68}
69
70impl Default for CameraLerp {
71    fn default() -> Self {
72        Self { factor: Vec2::ONE }
73    }
74}
75
76/// Component that specifies the cameras lead amount
77#[derive(Component, Default, Clone, Copy, PartialEq, Debug, Reflect)]
78pub struct CameraLead {
79    /// The amount to lead the cameras target by
80    pub lead_amount: Vec2,
81    /// The last position of the camera's target, used to calculate the lead
82    pub last_target_position: Option<Position2D>,
83}
84
85impl CameraLead {
86    /// Creates a new lead
87    pub fn new(lead_amount: Vec2) -> Self {
88        Self {
89            lead_amount,
90            last_target_position: None,
91        }
92    }
93}
94
95/// Bundles together the necessary components for a 2D camera
96#[derive(Bundle, Default)]
97pub struct CameraBundle2D {
98    /// 2D spatial bundle
99    pub spatial: SpatialBundle2DRaw,
100    /// 2D camera bundle from Bevy
101    pub camera_bundle: Camera2dBundle,
102    /// The camera's style
103    pub style: CameraStyle,
104    /// The camera's lerp factor
105    pub lerp: CameraLerp,
106    /// The camera's lead amount
107    pub lead: CameraLead,
108    /// The camera's target
109    pub target: CameraTarget,
110}