Collision on Y axis seems to work
This commit is contained in:
		
							parent
							
								
									89295b9283
								
							
						
					
					
						commit
						cd1befafa5
					
				@ -8,6 +8,7 @@ use sfml::window::Event;
 | 
				
			|||||||
use sfml::window::Key;
 | 
					use sfml::window::Key;
 | 
				
			||||||
use sfml::graphics::{
 | 
					use sfml::graphics::{
 | 
				
			||||||
    IntRect,
 | 
					    IntRect,
 | 
				
			||||||
 | 
					    FloatRect,
 | 
				
			||||||
    View,
 | 
					    View,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -146,6 +147,10 @@ impl Character {
 | 
				
			|||||||
        View::new(self.position, Vector2::new(24.0 * 16.0, 24.0 * 9.0))
 | 
					        View::new(self.position, Vector2::new(24.0 * 16.0, 24.0 * 9.0))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the collision bounding box of the character.
 | 
				
			||||||
 | 
					    pub fn bbox(&self) -> FloatRect {
 | 
				
			||||||
 | 
					        FloatRect::new(self.position.x, self.position.y, 32.0, 32.0)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Updatable for Character {
 | 
					impl Updatable for Character {
 | 
				
			||||||
@ -229,8 +234,4 @@ impl Drawable for Character {
 | 
				
			|||||||
    fn position(&self) -> Vector2<f32> {
 | 
					    fn position(&self) -> Vector2<f32> {
 | 
				
			||||||
        self.position
 | 
					        self.position
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn origin(&self) -> Vector2<f32> {
 | 
					 | 
				
			||||||
        Vector2::new(16.0, 16.0)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,22 @@
 | 
				
			|||||||
use sfml::system::Vector2;
 | 
					use sfml::system::Vector2;
 | 
				
			||||||
use sfml::graphics::IntRect;
 | 
					use sfml::graphics::{
 | 
				
			||||||
 | 
					    IntRect,
 | 
				
			||||||
 | 
					    FloatRect
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use engine::texture::Texture;
 | 
					use engine::texture::Texture;
 | 
				
			||||||
use engine::renderer::Drawable;
 | 
					use engine::renderer::Drawable;
 | 
				
			||||||
use engine::math::Matrix;
 | 
					use engine::math::Matrix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// This enum represents if the collision happens on the X axis or the Y axis.
 | 
				
			||||||
 | 
					pub enum CollisionAxis {
 | 
				
			||||||
 | 
					    /// The X axis.
 | 
				
			||||||
 | 
					    X,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The Y axis.
 | 
				
			||||||
 | 
					    Y,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// This struct represents the different sides from which a collision can occur.
 | 
					/// This struct represents the different sides from which a collision can occur.
 | 
				
			||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 | 
				
			||||||
pub struct CollisionTile {
 | 
					pub struct CollisionTile {
 | 
				
			||||||
@ -234,10 +246,6 @@ impl Drawable for PositionedTile {
 | 
				
			|||||||
    fn position(&self) -> Vector2<f32> {
 | 
					    fn position(&self) -> Vector2<f32> {
 | 
				
			||||||
        self.position.into()
 | 
					        self.position.into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn origin(&self) -> Vector2<f32> {
 | 
					 | 
				
			||||||
        Vector2::new(0.0, 0.0)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The map represents the tiles contained in a level.
 | 
					/// The map represents the tiles contained in a level.
 | 
				
			||||||
@ -351,10 +359,48 @@ impl Map {
 | 
				
			|||||||
        self.tiles.cols()
 | 
					        self.tiles.cols()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Checks whether the bounding box collides with an element of the map
 | 
				
			||||||
 | 
					    pub fn collides_bbox(&self, old: FloatRect, new: FloatRect) -> Option<(CollisionAxis, Vector2<f32>)> {
 | 
				
			||||||
 | 
					        // Top left corner
 | 
				
			||||||
 | 
					        if let Some((axis, collision)) = self.collides_point(
 | 
				
			||||||
 | 
					            Vector2::new(old.left, old.top),
 | 
				
			||||||
 | 
					            Vector2::new(new.left, new.top),
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            return Some((axis, collision));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Top right corner
 | 
				
			||||||
 | 
					        if let Some((axis, collision)) = self.collides_point(
 | 
				
			||||||
 | 
					            Vector2::new(old.left + old.width, old.top),
 | 
				
			||||||
 | 
					            Vector2::new(new.left + new.width, new.top),
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            return Some((axis, collision - Vector2::new(new.width, 0.0)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Bottom left corner
 | 
				
			||||||
 | 
					        if let Some((axis, collision)) = self.collides_point(
 | 
				
			||||||
 | 
					            Vector2::new(old.left, old.top + old.height),
 | 
				
			||||||
 | 
					            Vector2::new(new.left, new.top + new.height),
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            return Some((axis, collision - Vector2::new(0.0, new.height)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Bottom right corner
 | 
				
			||||||
 | 
					        if let Some((axis, collision)) = self.collides_point(
 | 
				
			||||||
 | 
					            Vector2::new(old.left + old.width, old.top + old.height),
 | 
				
			||||||
 | 
					            Vector2::new(new.left + new.width, new.top + new.height),
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            return Some((axis, collision - Vector2::new(new.width, new.height)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Checks whether the vector (old, new) collides with an element of the map.
 | 
					    /// Checks whether the vector (old, new) collides with an element of the map.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Returns the height of the collision if any.
 | 
					    /// Returns the height of the collision if any.
 | 
				
			||||||
    pub fn collides(&self, old: Vector2<f32>, new: Vector2<f32>) -> Option<f32> {
 | 
					    pub fn collides_point(&self, old: Vector2<f32>, new: Vector2<f32>)
 | 
				
			||||||
 | 
					        -> Option<(CollisionAxis, Vector2<f32>)> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let height = new.y - old.y;
 | 
					        let height = new.y - old.y;
 | 
				
			||||||
        let mut y = (old.y / 16.0).ceil() * 16.0;
 | 
					        let mut y = (old.y / 16.0).ceil() * 16.0;
 | 
				
			||||||
@ -372,7 +418,7 @@ impl Map {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if let Some((tile, _)) = self.tiles.get((row, col)) {
 | 
					                if let Some((tile, _)) = self.tiles.get((row, col)) {
 | 
				
			||||||
                    if tile.from_top {
 | 
					                    if tile.from_top {
 | 
				
			||||||
                        return Some(y);
 | 
					                        return Some((CollisionAxis::Y, Vector2::new(x, y)));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,9 +32,6 @@ pub trait Drawable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Returns the position on which the drawable should be drawn.
 | 
					    /// Returns the position on which the drawable should be drawn.
 | 
				
			||||||
    fn position(&self) -> Vector2<f32>;
 | 
					    fn position(&self) -> Vector2<f32>;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns the origin of the sprite.
 | 
					 | 
				
			||||||
    fn origin(&self) -> Vector2<f32>;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The game window.
 | 
					/// The game window.
 | 
				
			||||||
@ -92,7 +89,6 @@ impl Renderer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        use sfml::graphics::Transformable;
 | 
					        use sfml::graphics::Transformable;
 | 
				
			||||||
        sprite.set_position(drawable.position());
 | 
					        sprite.set_position(drawable.position());
 | 
				
			||||||
        sprite.set_origin(drawable.origin());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.window.draw(&sprite);
 | 
					        self.window.draw(&sprite);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,10 @@ use sfml::window::Event;
 | 
				
			|||||||
use sfml::graphics::View;
 | 
					use sfml::graphics::View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use engine::character::Character;
 | 
					use engine::character::Character;
 | 
				
			||||||
use engine::map::Map;
 | 
					use engine::map::{
 | 
				
			||||||
 | 
					    Map,
 | 
				
			||||||
 | 
					    CollisionAxis
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Contains everything needed to play.
 | 
					/// Contains everything needed to play.
 | 
				
			||||||
pub struct Scene {
 | 
					pub struct Scene {
 | 
				
			||||||
@ -75,14 +78,21 @@ impl Scene {
 | 
				
			|||||||
    pub fn update(&mut self, duration: &Duration) {
 | 
					    pub fn update(&mut self, duration: &Duration) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for c in &mut self.characters {
 | 
					        for c in &mut self.characters {
 | 
				
			||||||
            let old = c.position;
 | 
					            let old = c.bbox();
 | 
				
			||||||
            c.update(duration);
 | 
					            c.update(duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if let Some((axis, position)) = self.map.collides_bbox(old, c.bbox()) {
 | 
				
			||||||
            if let Some(height) = self.map.collides(old, c.position) {
 | 
					                match axis {
 | 
				
			||||||
                c.position.y = height;
 | 
					                    CollisionAxis::X => {
 | 
				
			||||||
 | 
					                        c.speed.x = 0.0;
 | 
				
			||||||
 | 
					                        c.position.x = position.x;
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    CollisionAxis::Y => {
 | 
				
			||||||
                        c.speed.y = 0.0;
 | 
					                        c.speed.y = 0.0;
 | 
				
			||||||
 | 
					                        c.position.y = position.y;
 | 
				
			||||||
                        c.ground_collision();
 | 
					                        c.ground_collision();
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                c.fall_off();
 | 
					                c.fall_off();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user