/// This module is intended to be used as a fixed-point physics system. /// The hope is that this will make deterministic physics easier, /// and therefore networking a bit less of a pain. use bevy::{ app::{Plugin, Update}, ecs::{component::Component, system::Query}, math::I64Vec2, }; const MAX_SPEED: i64 = 400; #[derive(Default, Debug)] pub struct Physics2DPlugin {} impl Plugin for Physics2DPlugin { fn build(&self, app: &mut bevy::app::App) { app.add_systems(Update, tick_physics); } } fn tick_physics(mut query: Query<&mut PhysicsBody2D>) { query.iter_mut().for_each(|mut pb| { pb.tick(); }); } #[derive(Default, Debug, Component)] pub struct PhysicsBody2D { pub pos: I64Vec2, pub vel: I64Vec2, } impl PhysicsBody2D { pub fn tick(&mut self) { self.pos += self.vel; } pub fn add_vel(&mut self, force: I64Vec2) { let mut vel = self.vel + force; if vel.length_squared() >= MAX_SPEED.pow(2) { let l = vel.length_squared(); let x = vel.x * vel.x; let y = vel.y * vel.y; vel.x = match vel.x { ..0 => (x * -MAX_SPEED) / l, _ => (x * MAX_SPEED) / l, }; vel.y = match vel.y { ..0 => (y * -MAX_SPEED) / l, _ => (y * MAX_SPEED) / l, }; } self.vel = vel; } }