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§

source

type InputDataType

This type should be generated by MainLoopRoot::sleep_and_get_input_data() and will be passed to MainLoopRoot::frame()

Required Methods§

source

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
}
source

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§

source

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

source

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);
Examples found in repository?
examples/game-loop-root.rs (line 40)
37
38
39
40
41
fn main() {
    let mut game = Game::new();

    game.main_loop(FPS);
}

Implementors§