Trait gemini_engine::gameloop::with_root::MainLoopRoot
source · pub trait MainLoopRoot {
type InputDataType;
// Required methods
fn frame(&mut self, input_data: Option<Self::InputDataType>);
fn render_frame(&mut self);
// Provided methods
fn sleep_and_get_input_data(
&self,
fps: f32,
elapsed: Duration
) -> (bool, Option<Self::InputDataType>) { ... }
fn main_loop(&mut self, fps: f32) { ... }
}Expand description
This is an alternative way to handle the gameloop, separate from fps_gameloop!. It takes on a more object oriented approach where everything related to the game is stored inside a single struct which implements this trait.
Check out the example, a version of quick-start.rs (the example from the elements doc page) rewritten using MainLoopRoot. While in that particular case it might appear to have a lot of boilerplate code, it can make your game much easier to manage as you add more things and scale it
This trait’s separate functions have more documentation to explain further details
Required Associated Types§
sourcetype InputDataType
type InputDataType
This type should be generated by MainLoopRoot::sleep_and_get_input_data() and will be passed to MainLoopRoot::frame()
Required Methods§
sourcefn frame(&mut self, input_data: Option<Self::InputDataType>)
fn frame(&mut self, input_data: Option<Self::InputDataType>)
This is where the main logic of your game - handling input, moving objects, handling collisions, etc.
§Example
// --inside impl MainLoopRoot for Game--
fn frame(&mut self, input_data: Option<Self::InputDataType>) {
self.player.pos.x += 1; // player has a pos: Vec2D field
}sourcefn render_frame(&mut self)
fn render_frame(&mut self)
All rendering code (blitting, printing to the screen, etc.) should be called in here. If the bool value returned by MainLoopRoot::sleep_and_get_input_data() is true, this won’t run and nothing should be printed to the screen
§Example
Here’s an example of what a render_frame trait implementation might look like, assuming your root struct has a view: View property for your main view
// --inside impl MainLoopRoot for Game--
fn render_frame(&mut self) {
self.view.clear();
for enemy in &self.enemies { // Go through a vector of Enemy structs (all of which would implement ViewElement)
self.view.blit(enemy, Wrapping::Ignore);
}
self.view.blit(&self.player, Wrapping::Ignore);
self.view.display_render().unwrap();
}Provided Methods§
sourcefn sleep_and_get_input_data(
&self,
fps: f32,
elapsed: Duration
) -> (bool, Option<Self::InputDataType>)
fn sleep_and_get_input_data( &self, fps: f32, elapsed: Duration ) -> (bool, Option<Self::InputDataType>)
The function used to sleep for the appropriate amount based on the FPS. Uses gameloop::sleep_fps by default and will return None for the InputDataType. The returned bool value should represent whether or not to skip rendering on the next frame
sourcefn main_loop(&mut self, fps: f32)
fn main_loop(&mut self, fps: f32)
The main loop function of the main loop root. This shouldnt be overriden. The fps parameter will be passed straight to sleep_and_get_input(). See the MainLoopRoot documentation for more info
const FPS: f32 = 30.0;
let mut game = Game::new(); // Implements MainLoopRoot and has a function that sets up all the game objects
game.main_loop(FPS);