use crate::Danmu;
pub enum Collision {
Separate { closest_dis: f64 },
NotEnoughTime { closest_dis: f64 },
Collide { time_needed: f64 },
}
#[derive(Debug, Clone)]
pub struct Lane {
last_shoot_time: f64,
last_length: u32,
}
impl Lane {
pub fn draw(danmu: &Danmu) -> Self {
Lane {
last_shoot_time: danmu.timeline_s,
last_length: danmu.length(),
}
}
pub fn draw_fixed(danmu: &Danmu) -> Self {
Lane {
last_shoot_time: danmu.timeline_s,
last_length: 0,
}
}
pub fn available_for(&self, other: &Danmu, config: &super::Config) -> Collision {
#[allow(non_snake_case)]
let T = config.duration;
#[allow(non_snake_case)]
let W = config.width as f64;
let t1 = self.last_shoot_time;
let t2 = other.timeline_s;
let l1 = self.last_length as f64;
let l2 = other.length() as f64;
let v1 = (W + l1) as f64 / T;
let v2 = (W + l2) as f64 / T;
let delta_t = t2 - t1;
let delta_x = v1 * delta_t - l1;
if delta_x < 0.0 {
if l2 <= l1 {
Collision::Collide {
time_needed: -delta_x / v1,
}
} else {
let time_needed = (t1 + T - W / v2) - t2;
Collision::Collide { time_needed }
}
} else {
let l2 = other.length() as f64;
if l2 <= l1 {
Collision::Separate {
closest_dis: delta_x,
}
} else {
let pos = v2 * (T - delta_t);
if pos < W {
Collision::NotEnoughTime {
closest_dis: W - pos,
}
} else {
Collision::Collide {
time_needed: (pos - W) / v2,
}
}
}
}
}
}