Start to do collisions
This commit is contained in:
		
							parent
							
								
									3e8ae2d496
								
							
						
					
					
						commit
						6b098f6cde
					
				
							
								
								
									
										
											BIN
										
									
								
								assets/textures/overworld-raw.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/textures/overworld-raw.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 56 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								assets/textures/overworld.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/textures/overworld.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										128
									
								
								src/engine/map/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/engine/map/mod.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,128 @@
 | 
			
		||||
use sfml::system::Vector2;
 | 
			
		||||
use sfml::graphics::IntRect;
 | 
			
		||||
 | 
			
		||||
use engine::texture::Texture;
 | 
			
		||||
use engine::renderer::Drawable;
 | 
			
		||||
use engine::math::Matrix;
 | 
			
		||||
 | 
			
		||||
/// This struct represents the different type of tiles that can exist in our maps.
 | 
			
		||||
#[derive(Copy, Clone, PartialEq, Eq)]
 | 
			
		||||
pub enum Tile {
 | 
			
		||||
    /// A tile that contains nothing.
 | 
			
		||||
    Empty,
 | 
			
		||||
 | 
			
		||||
    /// A solid tile.
 | 
			
		||||
    Solid
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Tile {
 | 
			
		||||
    /// Returns the offset to the tile in the texture.
 | 
			
		||||
    pub fn offset(&self) -> (i32, i32) {
 | 
			
		||||
        match *self {
 | 
			
		||||
            Tile::Empty => (0, 0),
 | 
			
		||||
            Tile::Solid => (16, 0),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A tile and its position.
 | 
			
		||||
pub struct PositionedTile {
 | 
			
		||||
    /// The tile of the positioned tile.
 | 
			
		||||
    pub tile: Tile,
 | 
			
		||||
 | 
			
		||||
    /// The position of the positioned tile.
 | 
			
		||||
    pub position: (f32, f32),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Drawable for PositionedTile {
 | 
			
		||||
    fn texture(&self) -> Texture {
 | 
			
		||||
        Texture::Overworld
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn texture_rect(&self) -> IntRect {
 | 
			
		||||
        let offset = self.tile.offset();
 | 
			
		||||
        IntRect::new(offset.0, offset.1, 16, 16)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn position(&self) -> Vector2<f32> {
 | 
			
		||||
        self.position.into()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The map represents the tiles contained in a level.
 | 
			
		||||
pub struct Map {
 | 
			
		||||
 | 
			
		||||
    /// The tiles contained in the level.
 | 
			
		||||
    tiles: Matrix<Tile>,
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Map {
 | 
			
		||||
 | 
			
		||||
    /// Creates a map full of nothing, with a ground at the bottom.
 | 
			
		||||
    pub fn new(rows: usize, cols: usize) -> Map {
 | 
			
		||||
 | 
			
		||||
        let mut tiles = Matrix::from_size(rows, cols, Tile::Empty);
 | 
			
		||||
        let rows = tiles.rows();
 | 
			
		||||
 | 
			
		||||
        for i in 0 .. tiles.cols() {
 | 
			
		||||
            tiles[(rows - 1, i)] = Tile::Solid;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tiles[(25, 12)] = Tile::Solid;
 | 
			
		||||
        tiles[(25, 13)] = Tile::Solid;
 | 
			
		||||
        tiles[(25, 14)] = Tile::Solid;
 | 
			
		||||
        tiles[(25, 15)] = Tile::Solid;
 | 
			
		||||
 | 
			
		||||
        Map {
 | 
			
		||||
            tiles: tiles,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns an iterator to the positioned tiles.
 | 
			
		||||
    pub fn at(&self, row: usize, col: usize) -> PositionedTile {
 | 
			
		||||
        PositionedTile {
 | 
			
		||||
            tile: self.tiles[(row, col)],
 | 
			
		||||
            position: (col as f32 * 16.0, row as f32 * 16.0),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the number of rows of the map.
 | 
			
		||||
    pub fn rows(&self) -> usize {
 | 
			
		||||
        self.tiles.rows()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the number of columns of the map.
 | 
			
		||||
    pub fn cols(&self) -> usize {
 | 
			
		||||
        self.tiles.cols()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Checks whether the vector (old, new) collides with an element of the map.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Returns the height of the collision if any.
 | 
			
		||||
    pub fn collides(&self, old: Vector2<f32>, new: Vector2<f32>) -> Option<f32> {
 | 
			
		||||
 | 
			
		||||
        let height = new.y - old.y;
 | 
			
		||||
        let mut y = (old.y / 16.0).ceil() * 16.0;
 | 
			
		||||
 | 
			
		||||
        while y < new.y {
 | 
			
		||||
 | 
			
		||||
            let current_height = y - old.y;
 | 
			
		||||
            let x = old.x + (new.x - old.x) * current_height / height;
 | 
			
		||||
 | 
			
		||||
            // Find tile on x, y
 | 
			
		||||
            let row = (y / 16.0) as usize + 2;
 | 
			
		||||
            let col = (x / 16.0) as usize + 1;
 | 
			
		||||
 | 
			
		||||
            if let Some(Tile::Solid) = self.tiles.get((row, col)) {
 | 
			
		||||
                return Some(y);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            y += 16.0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ impl<T> Matrix<T> where T: Clone {
 | 
			
		||||
impl<T> Matrix<T> {
 | 
			
		||||
    /// Converts an a pair corresponding to the row and columns into an integer.
 | 
			
		||||
    pub fn to_usize(&self, (row, col): (usize, usize)) -> usize {
 | 
			
		||||
        self.cols * col + row
 | 
			
		||||
        self.rows * col + row
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the number of rows.
 | 
			
		||||
@ -57,6 +57,15 @@ impl<T> Matrix<T> {
 | 
			
		||||
    pub fn cols(&self) -> usize {
 | 
			
		||||
        self.cols
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the tile if any, none otherwise.
 | 
			
		||||
    pub fn get(&self, (row, col): (usize, usize)) -> Option<&T> {
 | 
			
		||||
        if row < self.rows && col < self.cols {
 | 
			
		||||
            Some(&self[(row, col)])
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> Index<(usize, usize)> for Matrix<T> {
 | 
			
		||||
 | 
			
		||||
@ -19,3 +19,6 @@ pub mod renderer;
 | 
			
		||||
 | 
			
		||||
/// This module contains everything related to physics.
 | 
			
		||||
pub mod physics;
 | 
			
		||||
 | 
			
		||||
/// This module contains the map structure.
 | 
			
		||||
pub mod map;
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,16 @@ impl Renderer {
 | 
			
		||||
 | 
			
		||||
    /// 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 {
 | 
			
		||||
                self.draw(&map.at(i, j));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for c in scene.characters() {
 | 
			
		||||
            self.draw(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ use std::time::Duration;
 | 
			
		||||
use sfml::window::Event;
 | 
			
		||||
 | 
			
		||||
use engine::character::Character;
 | 
			
		||||
use engine::map::Map;
 | 
			
		||||
 | 
			
		||||
/// Contains everything needed to play.
 | 
			
		||||
pub struct Scene {
 | 
			
		||||
@ -10,6 +11,9 @@ pub struct Scene {
 | 
			
		||||
    /// The characters contained in the scene.
 | 
			
		||||
    characters: Vec<Character>,
 | 
			
		||||
 | 
			
		||||
    /// The map of the scene.
 | 
			
		||||
    map: Map,
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Scene {
 | 
			
		||||
@ -18,6 +22,7 @@ impl Scene {
 | 
			
		||||
    pub fn new() -> Scene {
 | 
			
		||||
        Scene {
 | 
			
		||||
            characters: vec![],
 | 
			
		||||
            map: Map::new(30, 30),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -30,10 +35,12 @@ impl Scene {
 | 
			
		||||
    pub fn update(&mut self, duration: &Duration) {
 | 
			
		||||
 | 
			
		||||
        for c in &mut self.characters {
 | 
			
		||||
            let old = c.position;
 | 
			
		||||
            c.update(duration);
 | 
			
		||||
 | 
			
		||||
            if c.position.y > 500.0 {
 | 
			
		||||
                c.position.y = 500.0;
 | 
			
		||||
 | 
			
		||||
            if let Some(height) = self.map.collides(old, c.position) {
 | 
			
		||||
                c.position.y = height;
 | 
			
		||||
                c.speed.y = 0.0;
 | 
			
		||||
                c.ground_collision();
 | 
			
		||||
            }
 | 
			
		||||
@ -52,6 +59,11 @@ impl Scene {
 | 
			
		||||
        &self.characters
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns a reference to the map.
 | 
			
		||||
    pub fn map(&self) -> &Map {
 | 
			
		||||
        &self.map
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Trait that needs to be implemented for everything that can be updatable.
 | 
			
		||||
 | 
			
		||||
@ -58,6 +58,7 @@ macro_rules! make_textures {
 | 
			
		||||
 | 
			
		||||
make_textures!(
 | 
			
		||||
    Mario, mario, make_mario_texture, "../../../assets/textures/mario.png",
 | 
			
		||||
    Overworld, overworld, make_overworld_texture, "../../../assets/textures/overworld.png",
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
impl TextureManager {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user