use std::time::Instant; use sfml::graphics::{Color, IntRect, RenderTarget, RenderWindow, Sprite, View}; use sfml::window::{Event, Style}; use sfml::system::Vector2; use crate::engine::map::GraphicTile; use crate::engine::scene::Scene; use crate::engine::texture::{Texture, TextureManager}; /// 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; } /// 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, fullscreen: bool) -> Renderer { let mut window = RenderWindow::new( (width, height), "Free Rusty Maker", if fullscreen { Style::FULLSCREEN } else { Style::CLOSE }, &Default::default(), ); window.set_vertical_sync_enabled(true); window.set_framerate_limit(60); Renderer { 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(&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 { self.window.poll_event() } }