use cgmath::{Deg, InnerSpace, Vector2}; use nalgebra::vector; use rapier2d::dynamics::RigidBody; use crate::{util, ShipPhysicsHandle}; use galactica_content as content; use galactica_gameobject as object; use galactica_render::ObjectSprite; pub struct ShipControls { pub left: bool, pub right: bool, pub thrust: bool, pub guns: bool, } impl ShipControls { pub fn new() -> Self { ShipControls { left: false, right: false, thrust: false, guns: false, } } } /// A ship instance in the physics system pub struct ShipWorldObject { /// TODO pub physics_handle: ShipPhysicsHandle, /// TODO pub ship: object::Ship, /// TODO pub controls: ShipControls, } impl ShipWorldObject { /// Make a new ship pub fn new(ship: object::Ship, physics_handle: ShipPhysicsHandle) -> Self { ShipWorldObject { physics_handle, ship, controls: ShipControls::new(), } } /// Step this ship's state by t seconds pub fn step(&mut self, r: &mut RigidBody, t: f32) { let ship_rot = util::rigidbody_rotation(r); let engine_force = ship_rot * t; if self.controls.thrust { r.apply_impulse( vector![engine_force.x, engine_force.y] * self.ship.outfits.stat_sum().engine_thrust, true, ); } if self.controls.right { r.apply_torque_impulse(self.ship.outfits.stat_sum().steer_power * -100.0 * t, true); } if self.controls.left { r.apply_torque_impulse(self.ship.outfits.stat_sum().steer_power * 100.0 * t, true); } for i in self.ship.outfits.iter_guns() { i.cooldown -= t; } } /// Get this ship's sprite pub fn get_sprite(&self, ct: &content::Content, r: &RigidBody) -> ObjectSprite { let ship_pos = util::rigidbody_position(r); let ship_rot = util::rigidbody_rotation(r); // Sprites point north at 0 degrees let ship_ang: Deg = ship_rot.angle(Vector2 { x: 0.0, y: 1.0 }).into(); let s = ct.get_ship(self.ship.handle); ObjectSprite { pos: (ship_pos.x, ship_pos.y, 1.0).into(), texture: s.sprite_texture, angle: -ship_ang, size: s.size, children: if self.controls.thrust { Some(self.ship.outfits.get_engine_flares()) } else { None }, } } }