I use the follow code to measuring fps.
impl event::EventHandler for App {
fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::clear(ctx);
println!("FPS: {}", ggez::timer::get_fps(ctx));
graphics::present(ctx);
Ok(())
}
}
FPS: 1228.6385824459492
FPS: 1118.5031743120085
FPS: 1028.1549964220205
....... about 150 frames .......
FPS: 60.05427825777494
FPS: 60.05327566297165
FPS: 60.04459271722737
FPS: 60.057084258587786
FPS: 60.060687721301115
FPS: 60.05724656742807
FPS: 60.051757408675385
FPS: 60.04946755037865
FPS: 60.04679927441849
FPS: 60.05704819007574
FPS: 60.063858693285525
FPS: 60.054094326005085
FPS: 60.06029452967834
FPS: 60.047177866706306
FPS: 59.91234823453287
FPS: 60.053614666101595
FPS: 60.060756259817296
FPS: 60.06152823075014
FPS: 60.06709855310973
FPS: 60.07317152584533
FPS: 60.07846608141028
FPS: 60.060972698263825
FPS: 60.06805470325659
..........
After stabilization, fps about for 60.
Can I change this fps ?
Is there a setting?
If you are using the released crate, there is vsync flag on Conf that tells it to set the display rate to your monitor's refresh rate; in this case, 60 hz. This flag is on by default because it's usually a good idea anyway.
In the current git master, the flag has moved to conf.window_mode.vsync.
ggez::timer::get_fps() averages over the last couple hundred frames, so it takes a second or two for it to "warm up" and give consistent results.
If you have any further questions please feel free to re-open this.
Frame rate not only affect the display, sometimes it will also affect the game logic.
I hope there can be a way to set the frame rate, especially if the vsync is not enabled.
pub fn run(ctx, state) -> Result {
loop {
if (ticks_and_check(ctx)) {
sdl_events_handle();
state.update(ctx);
state.draw(ctx);
}
}
}
fn ticks_and_check(ctx) {
let delay_time = now_time - last_time;
if ctx.vsync || delay_time >= 1.0 / ctx.fps {
true
} else {
false
}
}
I am now no way to deal with this elegance, because event handle is wrapped.
I can only do this in an hack way.
I hope the engine can provide a feature.
The various ways of doing this, with pros and cons, are described well here: https://gafferongames.com/post/fix_your_timestep/
AstroBlasto and a couple of the other examples show how to do this well with ggez:
impl EventHandler for MainState {
fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
const DESIRED_FPS: u32 = 60;
while timer::check_update_time(ctx, DESIRED_FPS) {
...
}
}
....
}
This is basically the setup described by "Free the physics" in that article. timer::check_update_time() keeps track of how much time has passed since the last frame, and will decrement it in DESIRED_FPS-sized chunks and return true as long as you should keep running physics updates. It correctly keeps track of the remainder of the time so you don't get round-off errors between frames.
Doing interpolation for the remaining timestep, as described in "The Final Step", is left as an exercise to the reader. ;-)
Most helpful comment
The various ways of doing this, with pros and cons, are described well here: https://gafferongames.com/post/fix_your_timestep/
AstroBlasto and a couple of the other examples show how to do this well with ggez:
This is basically the setup described by "Free the physics" in that article.
timer::check_update_time()keeps track of how much time has passed since the last frame, and will decrement it inDESIRED_FPS-sized chunks and return true as long as you should keep running physics updates. It correctly keeps track of the remainder of the time so you don't get round-off errors between frames.Doing interpolation for the remaining timestep, as described in "The Final Step", is left as an exercise to the reader. ;-)