Added animation automata to ships and projectiles
parent
f4c0e91851
commit
132148fee3
|
@ -2,7 +2,7 @@ use crate::{AnimSectionHandle, Content, SectionEdge, SpriteHandle};
|
|||
|
||||
/// A single frame's state
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpriteAnimationFrame {
|
||||
pub struct AnimationState {
|
||||
/// The index of the texture we're fading from
|
||||
pub texture_a: u32,
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub struct SpriteAnimationFrame {
|
|||
pub fade: f32,
|
||||
}
|
||||
|
||||
impl SpriteAnimationFrame {
|
||||
impl AnimationState {
|
||||
/// Convenience method.
|
||||
/// Get texture index as an array
|
||||
pub fn texture_index(&self) -> [u32; 2] {
|
||||
|
@ -224,8 +224,8 @@ impl AnimAutomaton {
|
|||
}
|
||||
|
||||
/// Get the current frame of this animation
|
||||
pub fn get_texture_idx(&self) -> SpriteAnimationFrame {
|
||||
return SpriteAnimationFrame {
|
||||
pub fn get_texture_idx(&self) -> AnimationState {
|
||||
return AnimationState {
|
||||
texture_a: self.last_texture,
|
||||
texture_b: self.next_texture,
|
||||
fade: self.current_fade,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use galactica_content::{FactionHandle, Projectile};
|
||||
use galactica_content::{AnimAutomaton, AnimationState, Content, FactionHandle, Projectile};
|
||||
use rand::Rng;
|
||||
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
|
||||
|
||||
|
@ -8,6 +8,9 @@ pub struct PhysProjectile {
|
|||
/// This projectile's game data
|
||||
pub content: Projectile,
|
||||
|
||||
/// This projectile's sprite animation state
|
||||
anim: AnimAutomaton,
|
||||
|
||||
/// The remaining lifetime of this projectile, in seconds
|
||||
pub lifetime: f32,
|
||||
|
||||
|
@ -27,7 +30,8 @@ pub struct PhysProjectile {
|
|||
impl PhysProjectile {
|
||||
/// Create a new projectile
|
||||
pub fn new(
|
||||
content: Projectile, // TODO: use a handle
|
||||
ct: &Content,
|
||||
content: Projectile, // TODO: use a handle?
|
||||
rigid_body: RigidBodyHandle,
|
||||
faction: FactionHandle,
|
||||
collider: ColliderHandle,
|
||||
|
@ -36,6 +40,7 @@ impl PhysProjectile {
|
|||
let size_rng = content.size_rng;
|
||||
let lifetime = content.lifetime;
|
||||
PhysProjectile {
|
||||
anim: AnimAutomaton::new(ct, content.sprite),
|
||||
rigid_body,
|
||||
collider,
|
||||
content,
|
||||
|
@ -46,8 +51,9 @@ impl PhysProjectile {
|
|||
}
|
||||
|
||||
/// Process this projectile's state after `t` seconds
|
||||
pub fn tick(&mut self, t: f32) {
|
||||
pub fn tick(&mut self, ct: &Content, t: f32) {
|
||||
self.lifetime -= t;
|
||||
self.anim.step(ct, t)
|
||||
}
|
||||
|
||||
/// Has this projectile expired?
|
||||
|
@ -55,3 +61,10 @@ impl PhysProjectile {
|
|||
return self.lifetime < 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl PhysProjectile {
|
||||
/// Get this projectile's animation state
|
||||
pub fn get_anim_state(&self) -> AnimationState {
|
||||
self.anim.get_texture_idx()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use galactica_content::{Content, FactionHandle, ShipHandle};
|
||||
use galactica_content::{
|
||||
AnimAutomaton, AnimationState, Content, EnginePoint, FactionHandle, OutfitHandle, ShipHandle,
|
||||
};
|
||||
use nalgebra::{point, vector, Rotation2, Vector2};
|
||||
use rand::Rng;
|
||||
use rapier2d::{
|
||||
|
@ -51,7 +53,13 @@ pub struct PhysSimShip {
|
|||
pub collider: ColliderHandle,
|
||||
|
||||
/// This ship's game data
|
||||
pub data: ShipData,
|
||||
pub(crate) data: ShipData,
|
||||
|
||||
/// This ship's sprite animation state
|
||||
anim: AnimAutomaton,
|
||||
|
||||
/// Animation state for each of this ship's engines
|
||||
engine_anim: Vec<(EnginePoint, AnimAutomaton)>,
|
||||
|
||||
/// This ship's controls
|
||||
pub(crate) controls: ShipControls,
|
||||
|
@ -72,9 +80,11 @@ impl PhysSimShip {
|
|||
) -> Self {
|
||||
let ship_ct = ct.get_ship(handle);
|
||||
PhysSimShip {
|
||||
anim: AnimAutomaton::new(ct, ship_ct.sprite),
|
||||
rigid_body,
|
||||
collider,
|
||||
data: ShipData::new(ct, handle, faction, personality),
|
||||
engine_anim: Vec::new(),
|
||||
controls: ShipControls::new(),
|
||||
collapse_sequence: Some(ShipCollapseSequence::new(ship_ct.collapse.length)),
|
||||
}
|
||||
|
@ -88,6 +98,18 @@ impl PhysSimShip {
|
|||
collider: &mut Collider,
|
||||
) {
|
||||
self.data.step(res.t);
|
||||
self.anim.step(res.ct, res.t);
|
||||
|
||||
if self.controls.thrust {
|
||||
for (_, e) in &mut self.engine_anim {
|
||||
e.step(res.ct, res.t);
|
||||
}
|
||||
} else {
|
||||
for (_, e) in &mut self.engine_anim {
|
||||
e.reset(res.ct);
|
||||
}
|
||||
}
|
||||
|
||||
match self.data.get_state() {
|
||||
ShipState::Collapsing { .. } => {
|
||||
// Borrow checker hack, so we may pass self.data
|
||||
|
@ -197,9 +219,69 @@ impl PhysSimShip {
|
|||
}
|
||||
}
|
||||
|
||||
/// Public mutable
|
||||
impl PhysSimShip {
|
||||
/// Re-create this ship's engine flare animations
|
||||
/// Should be called whenever we change outfits
|
||||
fn update_flares(&mut self, ct: &Content) {
|
||||
// TODO: better way to pick flare sprite
|
||||
let mut flare = None;
|
||||
for (h, _) in self.data.get_outfits().iter_outfits() {
|
||||
let c = ct.get_outfit(*h);
|
||||
if c.engine_flare_sprite.is_some() {
|
||||
flare = c.engine_flare_sprite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if flare.is_none() {
|
||||
self.engine_anim = Vec::new();
|
||||
return;
|
||||
}
|
||||
|
||||
let flare = flare.unwrap();
|
||||
self.engine_anim = ct
|
||||
.get_ship(self.data.get_content())
|
||||
.engines
|
||||
.iter()
|
||||
.map(|e| (e.clone(), AnimAutomaton::new(ct, flare)))
|
||||
.collect();
|
||||
}
|
||||
|
||||
/// Add one outfit to this ship
|
||||
pub fn add_outfit(&mut self, ct: &Content, o: OutfitHandle) {
|
||||
self.data.add_outfit(ct.get_outfit(o));
|
||||
self.update_flares(ct);
|
||||
}
|
||||
|
||||
/// Add many outfits to this ship
|
||||
pub fn add_outfits(&mut self, ct: &Content, outfits: impl IntoIterator<Item = OutfitHandle>) {
|
||||
for o in outfits {
|
||||
self.data.add_outfit(ct.get_outfit(o));
|
||||
}
|
||||
self.update_flares(ct);
|
||||
}
|
||||
}
|
||||
|
||||
/// Public immutable
|
||||
impl PhysSimShip {
|
||||
/// Get this ship's control state
|
||||
pub fn get_controls(&self) -> &ShipControls {
|
||||
&self.controls
|
||||
}
|
||||
|
||||
/// Get this ship's engine animations
|
||||
pub fn iter_engine_anim(&self) -> impl Iterator<Item = &(EnginePoint, AnimAutomaton)> {
|
||||
self.engine_anim.iter()
|
||||
}
|
||||
|
||||
/// Get this ship's animation state
|
||||
pub fn get_anim_state(&self) -> AnimationState {
|
||||
self.anim.get_texture_idx()
|
||||
}
|
||||
|
||||
/// Get this ship's game data struct
|
||||
pub fn get_data(&self) -> &ShipData {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue