free-rusty-maker/src/engine/renderer/mod.rs

131 lines
3.1 KiB
Rust

use std::time::Instant;
use sfml::graphics::{
RenderWindow,
RenderTarget,
Sprite,
Color,
IntRect,
View,
};
use sfml::window::{
Style,
Event,
};
use sfml::system::{
Vector2,
};
use engine::texture::{Texture, TextureManager};
use engine::scene::Scene;
use engine::map::GraphicTile;
/// Our custom drawable trait.
pub trait Drawable {
/// Returns the texture of the drawable.
fn texture(&self) -> Texture;
/// Returns the coordinates to use on the texture.
fn texture_rect(&self) -> IntRect;
/// Returns the position on which the drawable should be drawn.
fn position(&self) -> Vector2<f32>;
}
/// The game window.
pub struct Renderer {
/// The window on which the rendering will be done.
window: RenderWindow,
/// The texture manager needed by the renderer.
texture_manager: TextureManager,
/// The global timer of the renderer.
started: Instant,
}
impl Renderer {
/// Creates a new renderer.
pub fn new(width: u32, height: u32) -> Renderer {
let mut window = RenderWindow::new(
(width, height),
"Free Rusty Maker",
Style::CLOSE,
&Default::default(),
);
window.set_vertical_sync_enabled(true);
window.set_framerate_limit(60);
Renderer {
window: window,
texture_manager: TextureManager::new(),
started: Instant::now(),
}
}
/// Returns the animation state of the renderer, between 0 and 3.
pub fn animation_state(&self) -> i32 {
let duration = Instant::now().duration_since(self.started);
let ns = 1_000_000_000 * duration.as_secs() + duration.subsec_nanos() as u64;
let result = (ns as usize / 250_000_000) % 4;
result as i32
}
/// Clears the window.
pub fn clear(&mut self) {
self.window.clear(&Color::rgb(135, 206, 235));
}
/// Draws a drawable.
pub fn draw<D: Drawable>(&mut self, drawable: &D) {
let texture = self.texture_manager.get(drawable.texture());
let mut sprite = Sprite::with_texture(&texture);
sprite.set_texture_rect(&drawable.texture_rect());
use sfml::graphics::Transformable;
sprite.set_position(drawable.position());
self.window.draw(&sprite);
}
/// Updates the view.
pub fn set_view(&mut self, view: &View) {
self.window.set_view(&view);
}
/// Draws a scene on the window.
pub fn draw_scene(&mut self, scene: &Scene) {
let map = scene.map();
let rows = map.rows();
let cols = map.cols();
for i in 0 .. rows {
for j in 0 .. cols {
let tile = map.at(i,j);
if tile.graphic != GraphicTile::Hidden {
self.draw(&tile);
}
}
}
for c in scene.characters() {
self.draw(c);
}
}
/// Triggers the display.
pub fn display(&mut self) {
self.window.display();
}
/// Check if there are new events, returns the top of the stack.
pub fn poll_event(&mut self) -> Option<Event> {
self.window.poll_event()
}
}