Skip to main content

fantasy_craft/physics/
components.rs

1use macroquad::prelude::*;
2use parry2d::shape::{SharedShape, Cuboid};
3use parry2d::na::Vector2;
4use serde::Deserialize;
5
6use crate::scene::scene_loader::ComponentLoader;
7
8#[derive(Deserialize, Debug, Default)]
9pub struct Vec2Data {
10    pub x: f32,
11    pub y: f32
12}
13
14#[derive(Deserialize, Debug, Default)]
15pub struct UVec2Data {
16    pub x: u32,
17    pub y: u32
18}
19
20#[derive(Debug, Clone, Copy)]
21#[allow(dead_code)]
22pub struct Transform {
23    pub position: Vec2,
24    pub rotation: Vec2,
25    pub scale: Vec2
26}
27
28impl Default for Transform {
29    fn default() -> Self {
30        Self {
31            position: Vec2::new(0.0, 0.0),
32            rotation: Vec2::new(0.0, 0.0),
33            scale: Vec2::new(1.0, 1.0)
34        }
35    }
36}
37
38#[derive(Deserialize, Debug, Default)]
39pub struct TransformLoaderData {
40    #[serde(default)]
41    pub position: Vec2Data,
42
43    #[serde(default)]
44    pub rotation: Vec2Data,
45
46    #[serde(default)]
47    pub scale: Vec2Data
48}
49
50pub struct TransformLoader;
51
52impl ComponentLoader for TransformLoader {
53    fn load(&self, ctx: &mut crate::prelude::Context, entity: hecs::Entity, data: &serde_json::Value) {
54        let loader_data: TransformLoaderData = serde_json::from_value(data.clone())
55            .unwrap_or_default();
56
57        let component = Transform {
58            position: vec2(loader_data.position.x, loader_data.position.y),
59            rotation: vec2(loader_data.rotation.x, loader_data.rotation.y),
60            scale: vec2(loader_data.scale.x, loader_data.scale.y)
61        };
62
63        ctx.world.insert_one(entity, component).expect("Failed to insert Transform");
64    }
65}
66
67#[derive(Debug, Clone, Copy)]
68#[allow(dead_code)]
69pub enum BodyType {
70    Static,
71    Dynamic,
72    Kinematic
73}
74
75#[derive(Debug, Clone)]
76pub struct RigidBody {
77    pub body_type: BodyType
78}
79
80impl RigidBody {
81    pub fn new(body_type: BodyType) -> Self {
82        Self {
83            body_type
84        }
85    }
86}
87
88#[derive(Deserialize, Debug, Default)]
89pub struct RigidBodyLoaderData {
90    pub body_type: String
91}
92
93pub struct RigidBodyLoader;
94
95impl ComponentLoader for RigidBodyLoader {
96    fn load(&self, ctx: &mut crate::prelude::Context, entity: hecs::Entity, data: &serde_json::Value) {
97        let loader_data: RigidBodyLoaderData = serde_json::from_value(data.clone())
98            .unwrap_or_default();
99
100        let body_type = match loader_data.body_type.as_str() {
101            "static" => BodyType::Static,
102            "dynamic" => BodyType::Dynamic,
103            "kinematic" => BodyType::Kinematic,
104            _ => {
105                println!("Warning: Type de corps non reconnu '{}', utilisation de Dynamic par défaut.", loader_data.body_type);
106                BodyType::Dynamic
107            }
108        };
109
110        let component = RigidBody {
111            body_type
112        };
113
114        ctx.world.insert_one(entity, component).expect("Failed to insert RigidBody");
115    }
116}
117
118#[derive(Debug, Clone)]
119#[allow(dead_code)]
120pub struct Collider {
121    pub shape: SharedShape,
122    pub half_extents: Vec2
123}
124
125impl Collider {
126    pub fn new_box(width: f32, height: f32) -> Self {
127        Self {
128            shape: SharedShape::new(Cuboid::new(Vector2::new(width / 2.0, height / 2.0))),
129            half_extents: vec2(width / 2.0, height / 2.0)
130        }
131    }
132}
133
134#[derive(Deserialize, Debug, Default)]
135pub struct ColliderLoaderData {
136    pub shape: String,
137    pub width: f32,
138    pub height: f32
139}
140
141pub struct ColliderLoader;
142
143impl ComponentLoader for ColliderLoader {
144    fn load(&self, ctx: &mut crate::prelude::Context, entity: hecs::Entity, data: &serde_json::Value) {
145        let loader_data: ColliderLoaderData = serde_json::from_value(data.clone())
146            .unwrap_or_default();
147
148        match loader_data.shape.as_str() {
149            "Box" => {
150                ctx.world.insert_one(entity, Collider::new_box(loader_data.width, loader_data.height)).expect("Failed to insert Collider shape Box");
151            },
152            _ => {
153                println!("Warning: Type de shape non reconnu '{}', utilisation de Box par défaut.", loader_data.shape);
154                ctx.world.insert_one(entity, Collider::new_box(loader_data.width, loader_data.height)).expect("Failed to insert Collider shape Box");
155            }
156        }
157    }
158}
159
160#[derive(Debug, Clone)]
161pub struct Velocity(pub Vec2);
162
163pub struct VelocityLoader;
164
165impl ComponentLoader for VelocityLoader {
166    fn load(&self, ctx: &mut crate::prelude::Context, entity: hecs::Entity, data: &serde_json::Value) {
167        let loader_data: Vec2Data = serde_json::from_value(data.clone())
168            .unwrap_or_default();
169
170        let component = Velocity(vec2(loader_data.x, loader_data.y));
171
172        ctx.world.insert_one(entity, component).expect("Failed to insert Velocity");
173    }
174}
175
176#[derive(Debug, Clone)]
177pub struct Speed(pub f32);
178
179pub struct SpeedLoader;
180
181impl ComponentLoader for SpeedLoader {
182    fn load(&self, ctx: &mut crate::prelude::Context, entity: hecs::Entity, data: &serde_json::Value) {
183        let loader_data: f32 = serde_json::from_value(data.clone())
184            .unwrap_or_default();
185
186        let component = Speed(loader_data);
187
188        ctx.world.insert_one(entity, component).expect("Failed to insert Speed");
189    }
190}