135 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
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<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, 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<D: Drawable>(&mut self, drawable: &D) {
 | 
						|
        self.translate_and_draw(drawable, (0.0, 0.0));
 | 
						|
    }
 | 
						|
 | 
						|
    /// Draws a drawable with a certain translation.
 | 
						|
    pub fn translate_and_draw<D: Drawable, V: Into<Vector2<f32>>>(&mut self, drawable: &D, translation: V) {
 | 
						|
        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() + translation.into());
 | 
						|
 | 
						|
        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()
 | 
						|
    }
 | 
						|
 | 
						|
    /// Returns a reference to the window.
 | 
						|
    pub fn window(&self) -> &RenderWindow {
 | 
						|
        &self.window
 | 
						|
    }
 | 
						|
 | 
						|
    /// Returns a mutable reference to the window.
 | 
						|
    pub fn window_mut(&mut self) -> &mut RenderWindow {
 | 
						|
        &mut self.window
 | 
						|
    }
 | 
						|
}
 |