Smooth camera and unit motion: display positions, camera target smoothing, pan speed setting

This commit is contained in:
Richard Zink committed 2026-11-04 13:56:11 +01:00
1 parent 583c3fcdaf
commit eb11cca8cb
10 files changed
+107 -23

No files matched your search

+36
View File
@@ -288,12 +288,20 @@ pub struct Ent {
pub target: Option<u8>, // attackers: side whose core (or gate) they march on
#[serde(default)]
pub chained: bool, // a lone creature chained in a sealed cave: joins when the cave is claimed
#[serde(skip, default = "zero_f32")]
pub disp_x: f32, // smoothed screen position (not part of the saved or synced world state)
#[serde(skip, default = "zero_f32")]
pub disp_y: f32,
}
fn yes() -> bool {
true
}
fn zero_f32() -> f32 {
0.0
}
impl Ent {
fn dummy() -> Ent {
Ent {
@@ -350,6 +358,8 @@ impl Ent {
side: 0,
target: None,
chained: false,
disp_x: 0.0,
disp_y: 0.0,
}
}
pub fn tile(&self) -> usize {
@@ -1129,6 +1139,8 @@ impl Game {
e.hero = hero;
e.x = x;
e.y = y;
e.disp_x = x;
e.disp_y = y;
e.level = level;
e.max_hp = s.hp * (1.0 + 0.15 * (level - 1) as f32);
e.hp = e.max_hp;
@@ -1178,6 +1190,30 @@ impl Game {
// ---------------------------------------------------------------- update
// smoothed positions for the screen only: the simulation stays fixed-step and deterministic
pub fn smooth_display(&mut self, dt: f32) {
if dt <= 0.0 {
return;
}
let k = (1.0 - (-22.0 * dt).exp()).clamp(0.0, 1.0);
for e in self.ents.iter_mut() {
if e.disp_x == 0.0 && e.disp_y == 0.0 {
e.disp_x = e.x;
e.disp_y = e.y;
continue;
}
let dx = e.x - e.disp_x;
let dy = e.y - e.disp_y;
if dx * dx + dy * dy > 4.0 {
e.disp_x = e.x;
e.disp_y = e.y;
} else {
e.disp_x += dx * k;
e.disp_y += dy * k;
}
}
}
pub fn update(&mut self, dt: f32) {
let mut steps = 0usize;
let cmds = if self.netplay.is_some() {