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.y = 0.0;
|
c.speed.x = 0.0;
|
||||||
c.ground_collision();
|
c.position.x = position.x;
|
||||||
|
},
|
||||||
|
CollisionAxis::Y => {
|
||||||
|
c.speed.y = 0.0;
|
||||||
|
c.position.y = position.y;
|
||||||
|
c.ground_collision();
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c.fall_off();
|
c.fall_off();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue