пятница, 14 февраля 2020 г.

Game loop in Rust + SDL2

Cargo.toml
----------
[dependencies.sdl2]
    version = "0.33"
    default-features = false
    features = ["ttf","image","gfx","mixer"]

main.rs
--------
mod game;
mod game_fsm;

use crate::game::Game;
use std::time::Duration;
use std::time::Instant;

const FPS: f64 = 60.0;
const DELAY_TIME: f64 = 1000.0 / FPS;

fn main() {
    let sdl2_init = Game::new("GAME", 1366, 768);
    //
    match sdl2_init {
        Ok(mut game) => {
            println!("Run game");
            game.init();
            while game.is_running() {
                let frame_start = Instant::now();
                game.events();
                game.update();
                game.render();
                let frame_end = Instant::now();
                let frame_time = elapsed_ms(frame_start, frame_end);
                //println!("Current frame time: {} ms", frame_time);
                if frame_time < DELAY_TIME {
                    std::thread::sleep(Duration::from_millis((DELAY_TIME - frame_time) as u64));
                }
            }
            println!("Exit game");
            game.clean();
        }
        Err(e) => {
            println!("SDL2 Error: {}", e);
        }
    }
}

pub fn elapsed_ms(t1: Instant, t2: Instant) -> f64 {
    // pls see code in book: Beginning Rust: From Novice to Professional, Carlo Milanesi
}

game.rs
--------
extern crate sdl2;

use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::{Sdl, EventPump};
use sdl2::render::WindowCanvas;

use crate::game_fsm::{GameFSM, GameStateType};
use crate::game_fsm::game_state_type::PlayState;

pub struct Game {
    running: bool,
    ctx: Sdl,
    cvs: WindowCanvas,
    evt: EventPump,
    fsm: Option<GameFSM>,
    last_frame: u32,
}

impl Game {
    pub fn new(_title: &str, _width: u32, _height: u32) -> Result<Self, String> {
        //init
        let sdl_context = sdl2::init()?;

        let video_subsystem = sdl_context.video()?;
        let window = video_subsystem.window(_title, _width, _height)
            .position_centered()
            .build().unwrap();
        let canvas = window.into_canvas().build().unwrap();
        let event_pump = sdl_context.event_pump()?;
        //return
        Ok(Game {
            running: true,
            ctx: sdl_context,
            cvs: canvas,
            evt: event_pump,
            fsm: None,
            last_frame: 0,
        })
    }
    pub fn init(&mut self) {
        let game_fsm = GameFSM::new();
        self.fsm = Some(game_fsm);
        //self.cvs.set_draw_color(Color::RGB(255, 255, 255));
    }
    pub fn events(&mut self) {
        for event in self.evt.poll_iter() {
            match event {
                Event::Quit { .. } |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    println!("[Esc]");
                    self.running = false;
                }
                Event::KeyDown { keycode: Some(Keycode::Space), .. } => {
                    println!("[Space]");
                    //let play_state = GameStateType::Play(PlayState::new());
                    //self.fsm.as_mut().unwrap().change_game_states_by_type(play_state);
                }
                _ => {}
            }
        }
    }
    pub fn update(&mut self) {
        let mut timer = self.ctx.timer().unwrap();
        let mut delta_time:f64 = (timer.ticks() - self.last_frame) as f64 / 1000.0;
        delta_time = if delta_time > 0.05 { 0.05 } else { delta_time };
        self.last_frame = timer.ticks();
        //self.fsm.unwrap().update(delta_time);
        //println!("Current delta time: {} ms", delta_time);
    }
    pub fn render(&mut self) {
        self.cvs.set_draw_color(Color::RGB(0, 0, 0));
        self.cvs.clear();
        //self.fsm.unwrap().render();
        self.cvs.present();
    }
    pub fn clean(&mut self) {
        //self.fsm.unwrap().clean();
    }
    pub fn is_running(&self) -> bool {
        self.running
    }
    pub fn quit(&mut self) {
        self.running = false;
    }
}

Vasili Perahud

Комментариев нет:

Отправить комментарий