@@ 1,8 1,11 @@
+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;
+
#[derive(Clone)]
pub struct Planet {
pub planet_type: PlanetType,
@@ 12,6 15,16 @@ pub struct Planet {
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<Planet>,
@@ 19,9 32,10 @@ pub struct Planets {
impl Planets {
pub fn make_planet(planets: &mut Vec<Planet>, planet_type: PlanetType, mass: f64, radius: f64, position: (f64, f64), rigid_body_set: &mut RigidBodySet, collider_set: &mut ColliderSet) {
- let collider = ColliderBuilder::ball(1000.0 / SCALE)
+ 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);
@@ 60,7 74,7 @@ impl Planets {
planet_type: planet.planet_type,
x: planet.position.0 * SCALE,
y: planet.position.1 * SCALE,
- radius: planet.radius,
+ radius: planet.radius * SCALE,
});
}
@@ 68,4 82,14 @@ impl Planets {
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)
+ }
}
@@ 2,6 2,7 @@
use std::{time::Duration, sync::Arc};
use log::{error};
+use nalgebra::vector;
use rapier2d_f64::prelude::{PhysicsPipeline, RigidBodyHandle};
use starkingdoms_protocol::{ProtocolPlanet, PlanetType, ProtocolPlayer};
use tokio::{time::sleep, sync::RwLock};
@@ 14,29 15,33 @@ pub async fn timer_main(mgr: ClientManager, physics_data: Arc<RwLock<PhysicsData
physics_data.write().await.tick(&mut pipeline);
- let physics_data = physics_data.read().await;
-
let mut protocol_players = vec![];
- for (player_id, player) in mgr.players.read().await.iter() {
- let player_handle = player.handle;
- let player_body = physics_data.rigid_body_set.get(player_handle).unwrap();
+ {
+ for (player_id, player) in mgr.players.write().await.iter() {
+ let mut physics_data = physics_data.write().await;
+ let player_handle = player.handle;
+ let player_body = physics_data.rigid_body_set.get_mut(player_handle).unwrap();
+ let planets = world_data.read().await;
+ let grav_force = planets.gravity((player_body.translation().x, player_body.translation().y), player_body.mass());
+ player_body.add_force(vector![grav_force.0, grav_force.1], true);
- let translation = player_body.translation();
- let rotation = player_body.rotation();
+ let translation = player_body.translation();
+ let rotation = player_body.rotation();
- let username;
- {
- let usernames = mgr.usernames.read().await;
- username = usernames.get(player_id).unwrap().clone();
- }
+ let username;
+ {
+ let usernames = mgr.usernames.read().await;
+ username = usernames.get(player_id).unwrap().clone();
+ }
- protocol_players.push(ProtocolPlayer {
- rotation: rotation.angle(),
- x: translation.x * SCALE,
- y: translation.y * SCALE,
- username,
- });
+ protocol_players.push(ProtocolPlayer {
+ rotation: rotation.angle(),
+ x: translation.x * SCALE,
+ y: translation.y * SCALE,
+ username,
+ });
+ }
}
for (_addr, client_thread) in mgr.handlers.read().await.iter() {