use nalgebra::{Vector2, vector}; use rapier2d_f64::prelude::{RigidBodyHandle, RigidBodySet, ColliderBuilder, RigidBodyBuilder, ColliderSet}; use starkingdoms_protocol::{PlanetType, ProtocolPlanet}; use crate::{SCALE, manager::ClientHandlerMessage}; //const GRAVITY: f64 = 0.001; const GRAVITY: f64 = 0.00006674; #[derive(Clone)] pub struct Planet { pub planet_type: PlanetType, pub body_handle: RigidBodyHandle, pub position: (f64, f64), pub radius: f64, pub mass: f64 } impl Planet { pub fn gravity(&self, position: (f64, f64), mass: f64) -> (f64, f64) { let distance = ((position.0 - self.position.0).powi(2) + (position.1 - self.position.1).powi(2)).sqrt(); let force = GRAVITY * ((self.mass * mass) / distance * distance); let mut direction = Vector2::new(self.position.0 - position.0, self.position.1 - position.1); direction.set_magnitude(force); (direction.x, direction.y) } } #[derive(Default, Clone)] pub struct Planets { pub planets: Vec, } impl Planets { pub fn make_planet(planets: &mut Vec, planet_type: PlanetType, mass: f64, radius: f64, position: (f64, f64), rigid_body_set: &mut RigidBodySet, collider_set: &mut ColliderSet) { let collider = ColliderBuilder::ball(radius / SCALE) .build(); let body = RigidBodyBuilder::fixed() .translation(vector![position.0, position.1]) .additional_mass(0.0); let body_handle = rigid_body_set.insert(body); collider_set.insert_with_parent(collider, body_handle, rigid_body_set); planets.push(Planet { planet_type, body_handle, position, radius, mass, }); } pub fn new(rigid_body_set: &mut RigidBodySet, collider_set: &mut ColliderSet) -> Planets { let mut planets = Vec::new(); Planets::make_planet( &mut planets, PlanetType::Earth, 2000.0, 1000.0, (100.0, 100.0), rigid_body_set, collider_set, ); Planets { planets } } pub fn to_protocol(&self) -> ClientHandlerMessage { let mut planets = vec![]; for planet in self.planets.clone() { planets.push(ProtocolPlanet { planet_type: planet.planet_type, x: planet.position.0 * SCALE, y: planet.position.1 * SCALE, radius: planet.radius, // DO NOT * SCALE }); } ClientHandlerMessage::PlanetData { planets } } pub fn gravity(&self, position: (f64, f64), mass: f64) -> (f64, f64) { let mut direction = Vector2::zeros(); for planet in self.planets.clone() { let planet_grav = planet.gravity(position, mass); direction.x = planet_grav.0; direction.y = planet_grav.1; } (direction.x, direction.y) } }