main.rs 3.1 KB
Newer Older
1 2 3
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Luke Jones's avatar
Luke Jones committed
4 5
#![allow(clippy::pedantic)]
#![allow(clippy::new_without_default)]
6
#![doc(html_root_url = "http://lukenukem.co.nz/rs_game_framework/")]
Luke Jones's avatar
Luke Jones committed
7

8 9 10
use std::time::Instant;

pub use particle2d;
11
pub use particle2d::vec2d;
12 13
use sdl2;
pub use tiny_ecs;
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

///
/// The manager module contains most I/O objects and interfaces
pub mod manager;

/// The `states` module generally contains 3 states; `menu`, `play`, and `pause`
///
/// * `menu` is what a player will see upon loading the game
/// * `play` is the state which manages all gamplay, including loading assets,
///   initializing objects, managing responses to input, updaing the required
///   objects, and any other related tasks
/// * `pause` is a state which the player should see upon *pausing* a game,
///   it could just display an overlay over the top of the main game state,
///   or it could be more complex with a mini-game, menus, anything.
pub mod states;

/// This is where the main game loop and associated functions live
pub mod game;

/// All resource management structs and functions
pub mod resource;

/// The `components` module is where game entity components live
pub mod components;

Luke Jones's avatar
Luke Jones committed
39 40 41
/// Player object and menu control bindings + input management
pub mod controls;

42 43 44
/// The possible messages between components
pub mod messaging;

45 46
type FP = f64;
const MS_PER_UPDATE: FP = 4.0;
Luke Jones's avatar
Luke Jones committed
47

48 49 50
#[derive(Debug)]
pub struct TimeStep {
    last_time: Instant,
51
    delta_time: FP,
52
    frame_count: u32,
53
    frame_time: FP,
54 55 56 57 58 59 60 61 62 63 64 65
}

impl TimeStep {
    pub fn new() -> TimeStep {
        TimeStep {
            last_time: Instant::now(),
            delta_time: 0.0,
            frame_count: 0,
            frame_time: 0.0,
        }
    }

66
    pub fn delta(&mut self) -> FP {
67
        let current_time = Instant::now();
68 69
        let delta = current_time.duration_since(self.last_time).as_micros()
            as FP
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
            * 0.001;
        self.last_time = current_time;
        self.delta_time = delta;
        delta
    }

    pub fn frame_rate(&mut self) -> Option<u32> {
        self.frame_count += 1;
        self.frame_time += self.delta_time;
        let tmp;
        if self.frame_time >= 1000.0 {
            tmp = self.frame_count;
            self.frame_count = 0;
            self.frame_time = 0.0;
            return Some(tmp);
        }
        None
    }
}
89 90 91 92 93 94

/// Game initialisation and main loop
pub fn main() {
    // An SDL context is needed before we can procceed
    let mut sdl_ctx = sdl2::init().unwrap();
    // TODO: initialize a settings store here, then load settings
95
    let mut game = game::Game::new(&mut sdl_ctx, 800, 600);
96

97
    let mut timestep = TimeStep::new();
Luke Jones's avatar
Luke Jones committed
98
    let mut lag = 0.0;
Luke Jones's avatar
Luke Jones committed
99
    'running: loop {
100
        if !game.running() {
Luke Jones's avatar
Luke Jones committed
101
            break 'running;
102 103 104
        }
        game.handle_events();

105
        lag += timestep.delta();
106

Luke Jones's avatar
Luke Jones committed
107
        while lag >= MS_PER_UPDATE {
108
            game.update(MS_PER_UPDATE * 0.01);
Luke Jones's avatar
Luke Jones committed
109
            lag -= MS_PER_UPDATE;
110
        }
111

112 113
        game.render(lag);
    }
Luke Jones's avatar
Luke Jones committed
114
}