Extract TimeStep
parent
34cb79bef0
commit
2e98f3eeda
75
src/main.rs
75
src/main.rs
|
@ -596,6 +596,54 @@ impl WorldState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TimeStep {
|
||||||
|
last_frame_time: Instant,
|
||||||
|
// Milliseconds
|
||||||
|
accum: u128,
|
||||||
|
fps_num: u16,
|
||||||
|
fps_den: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TimeStep {
|
||||||
|
pub fn new (fps_num: u16, fps_den: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
last_frame_time: Instant::now (),
|
||||||
|
accum: 0,
|
||||||
|
fps_num,
|
||||||
|
fps_den,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Automatically gets monotonic system time from Instant
|
||||||
|
// If you need something fancy just rewrite this.
|
||||||
|
// Returns: How many logics steps to run. Typically 0 or 1.
|
||||||
|
|
||||||
|
pub fn step (&mut self) -> u16 {
|
||||||
|
let frame_time = Instant::now ();
|
||||||
|
|
||||||
|
let fps_num_128: u128 = self.fps_num.into ();
|
||||||
|
let fps_den_128: u128 = self.fps_den.into ();
|
||||||
|
|
||||||
|
self.accum += (frame_time - self.last_frame_time).as_millis () * fps_num_128;
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
const MAX_FRAMES: u16 = 4;
|
||||||
|
|
||||||
|
for _ in 0..MAX_FRAMES {
|
||||||
|
if self.accum > fps_den_128 {
|
||||||
|
result += 1;
|
||||||
|
self.accum -= fps_den_128;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.last_frame_time = frame_time;
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main () {
|
fn main () {
|
||||||
let sdl_context = sdl2::init ().unwrap ();
|
let sdl_context = sdl2::init ().unwrap ();
|
||||||
let video_subsystem = sdl_context.video ().unwrap ();
|
let video_subsystem = sdl_context.video ().unwrap ();
|
||||||
|
@ -698,39 +746,18 @@ fn main () {
|
||||||
let stride = 4 * num_coords;
|
let stride = 4 * num_coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut last_frame_time = Instant::now ();
|
let mut time_step = TimeStep::new (60, 1000);
|
||||||
let mut frame = 0;
|
|
||||||
let mut timestep_accum = Duration::from_millis (0);
|
|
||||||
|
|
||||||
let mut state = WorldState::new ();
|
let mut state = WorldState::new ();
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump ().unwrap ();
|
let mut event_pump = sdl_context.event_pump ().unwrap ();
|
||||||
'running: loop {
|
'running: loop {
|
||||||
let frame_time = Instant::now ();
|
let frames_to_do = time_step.step ();
|
||||||
|
|
||||||
// Take 60 steps every 1,000 milliseconds.
|
|
||||||
// I know this is a float, but since we're multiplying it will
|
|
||||||
// be deterministic, since it's a whole number.
|
|
||||||
let fps_num = 60.0;
|
|
||||||
let fps_den = 1000;
|
|
||||||
|
|
||||||
timestep_accum += (frame_time - last_frame_time).mul_f32 (fps_num);
|
|
||||||
|
|
||||||
let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ());
|
let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ());
|
||||||
|
|
||||||
for _ in 0..4 {
|
for _ in 0..frames_to_do {
|
||||||
if timestep_accum > Duration::from_millis (fps_den) {
|
|
||||||
frame += 1;
|
|
||||||
timestep_accum -= Duration::from_millis (fps_den);
|
|
||||||
|
|
||||||
state.step (&controller);
|
state.step (&controller);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_frame_time = frame_time;
|
|
||||||
|
|
||||||
let _mouse = event_pump.mouse_state ();
|
let _mouse = event_pump.mouse_state ();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue