free-rusty-maker/src/app/game.rs

129 lines
3.5 KiB
Rust

use std::time::Instant;
use clap::{crate_version, App, Arg};
use sfml::window::{joystick, Event, Key};
use rusty::engine::character::Character;
use rusty::engine::controls::Controls;
use rusty::engine::map::Map;
use rusty::engine::renderer::Renderer;
use rusty::engine::scene::{Scene, State};
fn parse_resolution(res: &str) -> Result<(u32, u32), String> {
let split = res.split('x').collect::<Vec<_>>();
if split.len() != 2 {
return Err("Resolution should be WIDTHxHEIGHT".to_owned());
}
let width = match split[0].parse::<u32>() {
Ok(w) => w,
Err(_) => return Err("WIDTH must be an integer".to_owned()),
};
let height = match split[1].parse::<u32>() {
Ok(h) => h,
Err(_) => return Err("HEIGHT must be an integer".to_owned()),
};
Ok((width, height))
}
fn main() {
let matches = App::new("Rusty Maker")
.version(crate_version!())
.arg(
Arg::with_name("resolution")
.short("r")
.long("resolution")
.value_name("WIDTHxHEIGHT")
.takes_value(true)
.default_value("800x450")
.validator(|x| parse_resolution(&x).map(|_| ())),
)
.arg(
Arg::with_name("map")
.short("m")
.long("map")
.value_name("MAP")
.takes_value(true)
.default_value("assets/levels/level2.lvl")
.validator(|x| Map::from_file(x).map(|_| ()).map_err(|x| format!("{}", x))),
)
.arg(
Arg::with_name("fullscreen")
.short("f")
.long("fullscreen")
.takes_value(false),
)
.get_matches();
let resolution = parse_resolution(matches.value_of("resolution").unwrap()).unwrap();
let fullscreen = matches.is_present("fullscreen");
joystick::update();
let gamepads = Controls::all_gamepads();
let controls = if gamepads.is_empty() {
Controls::default_keyboard()
} else {
gamepads[0]
};
let mut character = Character::with_controls(controls);
character.set_position((10.0, 0.0));
let map = Map::from_file(matches.value_of("map").unwrap()).unwrap();
let mut scene = Scene::from_map(map);
scene.add(character);
let mut renderer = Renderer::new(resolution.0, resolution.1, fullscreen);
let mut after_loop = Instant::now();
let mut running = true;
loop {
// Manage the events
while let Some(event) = renderer.poll_event() {
match event {
// Quit the game if window is closed
Event::Closed => running = false,
// Quit the game if escape is pressed
Event::KeyPressed {
code: Key::Escape, ..
} => running = false,
_ => (),
}
scene.manage_event(&event);
}
// Manage the physics
let duration = Instant::now().duration_since(after_loop);
after_loop = Instant::now();
if scene.update(&duration) == State::Finished {
running = false;
}
// Update the view
if let Some(view) = scene.view() {
renderer.set_view(&view);
}
// Do the rendering
renderer.clear();
renderer.draw_scene(&scene);
// Display and manage the frame rate
renderer.display();
if !running {
break;
}
}
}