use bevy::prelude::*;
const TWEEN_DURATION: f32 = 0.25;
#[derive(Clone, Debug, Component)]
pub enum Tween {
Value {
eta: f32,
x: f32,
y: f32,
scale: f32,
xf: f32,
yf: f32,
scalef: f32,
remove_entity: bool,
},
Delete(f32),
}
impl Tween {
pub fn value() -> ValueBuilder {
ValueBuilder::default()
.eta(TWEEN_DURATION)
.scalef(1.0)
}
pub fn delete() -> Self {
Self::Delete(TWEEN_DURATION)
}
pub fn eta(&self) -> f32 {
match self {
Self::Value{ eta, .. } => *eta,
Self::Delete(eta) => *eta,
}
}
pub fn update(&mut self, dt: f32) -> TweenDone {
let v = 0f32.max(self.eta() - dt);
let mut delete = [false];
match self {
Self::Value {
eta,
x,
y,
scale,
xf,
yf,
scalef,
remove_entity,
} => {
let f = (*eta - v) / *eta;
*x += (*xf - *x) * f;
*y += (*yf - *y) * f;
*scale += (*scalef - *scale) * f;
*eta = v;
delete[0] = *remove_entity;
}
Self::Delete(eta) => {
*eta = v;
delete[0] = true;
}
}
TweenDone(v == 0.0, delete[0])
}
pub fn apply(&self, transform: &mut Transform) {
if let Self::Value { eta, x, y, scale, .. } = *self {
let z = if eta == 0.0 { 1.0 } else { transform.scale.z };
transform.translation.x = x;
transform.translation.y = y;
transform.scale = Vec3::splat(scale);
transform.scale.z = z;
}
}
}
#[derive(Debug)]
pub struct TweenDone(bool, bool);
impl TweenDone {
pub fn remove_component(&self) -> bool {
self.0 && !self.1
}
pub fn remove_entity(&self) -> bool {
self.0 && self.1
}
}
#[derive(Debug, Default)]
pub struct ValueBuilder {
eta: f32,
x: f32,
y: f32,
scale: f32,
xf: f32,
yf: f32,
scalef: f32,
remove_entity: bool,
}
impl ValueBuilder {
pub fn eta(mut self, eta: f32) -> Self {
self.eta = eta;
self
}
pub fn xy(mut self, x: f32, y: f32) -> Self {
self.x = x;
self.y = y;
self
}
pub fn xyf(mut self, xf: f32, yf: f32) -> Self {
self.xf = xf;
self.yf = yf;
self
}
pub fn scale(mut self, scale: f32) -> Self {
self.scale = scale;
self
}
pub fn scalef(mut self, scalef: f32) -> Self {
self.scalef = scalef;
self
}
pub fn remove_entity(mut self, remove_entity: bool) -> Self {
self.remove_entity = remove_entity;
self
}
}
impl From<ValueBuilder> for Tween {
fn from(builder: ValueBuilder) -> Self {
let ValueBuilder {
eta,
x, y,
scale,
xf, yf,
scalef,
remove_entity,
} = builder;
Tween::Value { eta, x, y, scale, xf, yf, scalef, remove_entity }
}
}