nightshade-api 0.43.0

Procedural high level API for the nightshade game engine
Documentation
//! Fire and forget animation. Each call captures the current value, eases
//! toward the target over the duration, and cleans up after itself. A new
//! animation on the same property replaces the one in flight.

use nightshade::prelude::*;

/// Glides the entity to `to` in its parent's space over `seconds`.
pub fn animate_position(
    world: &mut World,
    entity: Entity,
    to: Vec3,
    seconds: f32,
    easing: EasingFunction,
) {
    let Some(from) = world
        .core
        .get_local_transform(entity)
        .map(|transform| transform.translation)
    else {
        return;
    };
    world.resources.tweens.active.retain(|tween| {
        !(tween.entity == entity && matches!(tween.target, TweenTarget::Position { .. }))
    });
    world.resources.tweens.active.push(Tween {
        entity,
        target: TweenTarget::Position { from, to },
        duration_seconds: seconds,
        elapsed_seconds: 0.0,
        easing,
    });
}

/// Grows or shrinks the entity to `to` over `seconds`.
pub fn animate_scale(
    world: &mut World,
    entity: Entity,
    to: Vec3,
    seconds: f32,
    easing: EasingFunction,
) {
    let Some(from) = world
        .core
        .get_local_transform(entity)
        .map(|transform| transform.scale)
    else {
        return;
    };
    world.resources.tweens.active.retain(|tween| {
        !(tween.entity == entity && matches!(tween.target, TweenTarget::Scale { .. }))
    });
    world.resources.tweens.active.push(Tween {
        entity,
        target: TweenTarget::Scale { from, to },
        duration_seconds: seconds,
        elapsed_seconds: 0.0,
        easing,
    });
}

/// Fades the entity's base color to `to` over `seconds`.
pub fn animate_color(
    world: &mut World,
    entity: Entity,
    to: [f32; 4],
    seconds: f32,
    easing: EasingFunction,
) {
    let Some(from) = crate::appearance::owned_color(world, entity) else {
        return;
    };
    world.resources.tweens.active.retain(|tween| {
        !(tween.entity == entity && matches!(tween.target, TweenTarget::Color { .. }))
    });
    world.resources.tweens.active.push(Tween {
        entity,
        target: TweenTarget::Color { from, to },
        duration_seconds: seconds,
        elapsed_seconds: 0.0,
        easing,
    });
}

/// Kicks the active camera with a jitter that decays to nothing over
/// `seconds`. Strength is in world units, around 0.05 for a rumble and 0.3
/// for an explosion.
pub fn shake_camera(world: &mut World, strength: f32, seconds: f32) {
    let shake = &mut world.resources.tweens.shake;
    shake.strength = strength;
    shake.duration_seconds = seconds;
    shake.remaining_seconds = seconds;
}