Added basic unlanding animation

master
Mark 2024-01-12 18:16:20 -08:00
parent 079ee461af
commit 025a1df69e
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
7 changed files with 140 additions and 23 deletions

View File

@ -97,6 +97,11 @@ fn main() -> Result<()> {
None None
} }
} }
ShipState::UnLanding { .. } => {
let pos =
o.data.get_state().unlanding_position(&content).unwrap();
Some(Point2 { x: pos.x, y: pos.y })
}
ShipState::Landing { .. } => { ShipState::Landing { .. } => {
let pos = let pos =
o.data.get_state().landing_position(&content).unwrap(); o.data.get_state().landing_position(&content).unwrap();

View File

@ -1,7 +1,7 @@
//! GPUState routines for drawing items in a systemsim //! GPUState routines for drawing items in a systemsim
use bytemuck; use bytemuck;
use cgmath::{EuclideanSpace, InnerSpace, Point2, Point3, Vector2}; use cgmath::{EuclideanSpace, InnerSpace, Point2, Point3, Rad, Vector2};
use galactica_system::{data::ShipState, phys::util}; use galactica_system::{data::ShipState, phys::util};
use galactica_util::constants::OBJECT_SPRITE_INSTANCE_LIMIT; use galactica_util::constants::OBJECT_SPRITE_INSTANCE_LIMIT;
@ -60,6 +60,14 @@ impl GPUState {
ship_ang = from_angle + ((target_angle - from_angle) * 1f32.min(elapsed / 1.0)); ship_ang = from_angle + ((target_angle - from_angle) * 1f32.min(elapsed / 1.0));
ship_cnt = state.ct.get_ship(ship.data.get_content()); ship_cnt = state.ct.get_ship(ship.data.get_content());
} }
ShipState::UnLanding {
to_angle, elapsed, ..
} => {
ship_pos = ship.data.get_state().unlanding_position(state.ct).unwrap();
ship_ang = Rad(0.0) + ((to_angle - Rad(0.0)) * 1f32.min(elapsed / 1.0));
ship_cnt = state.ct.get_ship(ship.data.get_content());
}
} }
// Position adjusted for parallax // Position adjusted for parallax

View File

@ -41,7 +41,6 @@ impl Radar {
match player_ship.data.get_state() { match player_ship.data.get_state() {
ShipState::Dead => {} ShipState::Dead => {}
// TODO: radar follows while landing
ShipState::Landing { .. } => { ShipState::Landing { .. } => {
let pos = player_ship let pos = player_ship
.data .data
@ -51,6 +50,15 @@ impl Radar {
self.last_player_position = Point2 { x: pos.x, y: pos.y } self.last_player_position = Point2 { x: pos.x, y: pos.y }
} }
ShipState::UnLanding { .. } => {
let pos = player_ship
.data
.get_state()
.unlanding_position(&input.ct)
.unwrap();
self.last_player_position = Point2 { x: pos.x, y: pos.y }
}
ShipState::Landed { target } => { ShipState::Landed { target } => {
let landed_body = input.ct.get_system_object(*target); let landed_body = input.ct.get_system_object(*target);
self.last_player_position = Point2 { self.last_player_position = Point2 {
@ -150,7 +158,9 @@ impl Radar {
} }
// TODO: different color for landing? // TODO: different color for landing?
ShipState::Landing { .. } | ShipState::Collapsing { .. } => { ShipState::UnLanding { .. }
| ShipState::Landing { .. }
| ShipState::Collapsing { .. } => {
// TODO: configurable // TODO: configurable
[0.2, 0.2, 0.2, 1.0] [0.2, 0.2, 0.2, 1.0]
} }

View File

@ -43,7 +43,8 @@ impl Status {
max_shields = player_ship.data.get_outfits().get_shield_strength(); max_shields = player_ship.data.get_outfits().get_shield_strength();
max_hull = input.ct.get_ship(player_ship.data.get_content()).hull; max_hull = input.ct.get_ship(player_ship.data.get_content()).hull;
} }
ShipState::Landing { .. } ShipState::UnLanding { .. }
| ShipState::Landing { .. }
| ShipState::Landed { .. } | ShipState::Landed { .. }
| ShipState::Collapsing { .. } | ShipState::Collapsing { .. }
| ShipState::Flying => { | ShipState::Flying => {

View File

@ -47,7 +47,26 @@ pub enum ShipState {
/// The total amount of time, in seconds, we will spend landing /// The total amount of time, in seconds, we will spend landing
total: f32, total: f32,
/// The amount of time we've already spent playing the landing sequence /// The amount of time we've already spent playing this landing sequence
elapsed: f32,
},
/// This ship is taking off from a planet
/// (playing the animation)
UnLanding {
/// The point, in world coordinates, to which we're going
to_position: Point2<f32>,
/// The angle we'll be at when we arrive
to_angle: Rad<f32>,
/// The planet we're taking off from
from: SystemObjectHandle,
/// The total amount of time, in seconds, we will spend taking off
total: f32,
/// The amount of time we've already spent playing this unlanding sequence
elapsed: f32, elapsed: f32,
}, },
} }
@ -96,6 +115,8 @@ impl ShipState {
// TODO: atmosphere burn // TODO: atmosphere burn
// TODO: land at random point // TODO: land at random point
// TODO: don't jump camera // TODO: don't jump camera
// TODO: time by distance
// TODO: keep momentum
let pos = from_position + (diff * (elapsed / total)); let pos = from_position + (diff * (elapsed / total));
@ -108,6 +129,48 @@ impl ShipState {
_ => None, _ => None,
} }
} }
/// Compute position of this ship's sprite during its unlanding sequence
pub fn unlanding_position(&self, ct: &Content) -> Option<Point3<f32>> {
match self {
Self::UnLanding {
to_position,
from,
total,
elapsed,
..
} => Some({
let from = ct.get_system_object(*from);
let diff = to_position
- Point2 {
x: from.pos.x,
y: from.pos.y,
};
//let diff = diff - diff.normalize() * (target.size / 2.0) * 0.8;
// TODO: improve animation
// TODO: fade
// TODO: atmosphere burn
// TODO: land at random point
// TODO: don't jump camera
// TODO: time by distance
// TODO: keep momentum
let pos = Point2 {
x: from.pos.x,
y: from.pos.y,
} + (diff * (elapsed / total));
Point3 {
x: pos.x,
y: pos.y,
z: from.pos.z + ((1.0 - from.pos.z) * (elapsed / total)),
}
}),
_ => None,
}
}
} }
/// Represents all attributes of a single ship /// Represents all attributes of a single ship
@ -189,10 +252,16 @@ impl ShipData {
} }
/// Take off from `target` /// Take off from `target`
pub fn unland(&mut self) { pub fn unland(&mut self, to_position: Point2<f32>) {
match self.state { match self.state {
ShipState::Landed { .. } => { ShipState::Landed { target } => {
self.state = ShipState::Flying; self.state = ShipState::UnLanding {
to_position,
to_angle: Rad(1.0),
from: target,
total: 5.0,
elapsed: 0.0,
};
} }
_ => { _ => {
unreachable!("Called `unland` on a ship that isn't landed!") unreachable!("Called `unland` on a ship that isn't landed!")
@ -276,6 +345,17 @@ impl ShipData {
} }
} }
ShipState::UnLanding {
ref mut elapsed,
total,
..
} => {
*elapsed += t;
if *elapsed >= total {
self.state = ShipState::Flying;
}
}
ShipState::Landed { .. } => { ShipState::Landed { .. } => {
// Cooldown guns // Cooldown guns
for (_, c) in &mut self.gun_cooldowns { for (_, c) in &mut self.gun_cooldowns {

View File

@ -99,7 +99,10 @@ impl PhysSimShip {
ShipState::Flying => { ShipState::Flying => {
return self.step_live(res, rigid_body, collider); return self.step_live(res, rigid_body, collider);
} }
ShipState::Dead | ShipState::Landing { .. } | ShipState::Landed { .. } => {} ShipState::UnLanding { .. }
| ShipState::Dead
| ShipState::Landing { .. }
| ShipState::Landed { .. } => {}
} }
} }

View File

@ -77,10 +77,11 @@ impl<'a> PhysSim {
-util::rigidbody_rotation(r).angle(Vector2 { x: 0.0, y: 1.0 }), -util::rigidbody_rotation(r).angle(Vector2 { x: 0.0, y: 1.0 }),
); );
self.rigid_body_set let r = self.rigid_body_set.get_mut(ship.rigid_body).unwrap();
.get_mut(ship.rigid_body) r.set_enabled(false);
.unwrap() r.set_angvel(0.0, false);
.set_enabled(false); r.set_linvel(nalgebra::Vector2::new(0.0, 0.0), false);
self.collider_set self.collider_set
.get_mut(ship.collider) .get_mut(ship.collider)
.unwrap() .unwrap()
@ -91,16 +92,24 @@ impl<'a> PhysSim {
let ship = self.ships.get_mut(&collider).unwrap(); let ship = self.ships.get_mut(&collider).unwrap();
let obj = ship.data.get_state().landed_on().unwrap(); let obj = ship.data.get_state().landed_on().unwrap();
let obj = ct.get_system_object(obj); let obj = ct.get_system_object(obj);
ship.data.unland();
self.rigid_body_set let target_pos = Point2 {
.get_mut(ship.rigid_body) x: obj.pos.x + 100.0,
.unwrap() y: obj.pos.y + 100.0,
.set_position(point![obj.pos.x, obj.pos.y].into(), true); };
self.rigid_body_set
.get_mut(ship.rigid_body) ship.data.unland(target_pos);
.unwrap()
.set_enabled(true); let r = self.rigid_body_set.get_mut(ship.rigid_body).unwrap();
r.set_enabled(true);
r.set_position(
nalgebra::Vector2::new(target_pos.x, target_pos.y).into(),
true,
);
r.set_rotation(nalgebra::Rotation2::new(1.0).into(), false);
self.collider_set self.collider_set
.get_mut(ship.collider) .get_mut(ship.collider)
.unwrap() .unwrap()
@ -306,7 +315,8 @@ impl PhysSim {
to_remove.push(collider); to_remove.push(collider);
} }
ShipState::Landing { .. } ShipState::UnLanding { .. }
| ShipState::Landing { .. }
| ShipState::Landed { .. } | ShipState::Landed { .. }
| ShipState::Collapsing { .. } => { | ShipState::Collapsing { .. } => {
let ship = self.ships.get_mut(&collider).unwrap(); let ship = self.ships.get_mut(&collider).unwrap();